set structure for IR

This commit is contained in:
2024-08-21 04:10:36 +00:00
parent 03e33d0a0f
commit ed1ba4b59a
17 changed files with 1423 additions and 66 deletions

3
include/IR/IR.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
#include "IR_basic.h"
#include "IRBuilder.h"

54
include/IR/IRBuilder.h Normal file
View File

@ -0,0 +1,54 @@
#include <memory>
#include "IR_basic.h"
#include "ast/astnode_visitor.h"
class IRBuilder : public ASTNodeVirturalVisitor {
std::shared_ptr<ModuleItem> prog;
public:
// Structural AST Nodes
void ActuralVisit(FuncDef_ASTNode *node) override;
void ActuralVisit(ClassDef_ASTNode *node) override;
void ActuralVisit(Program_ASTNode *node) override;
// Statement AST Nodes
void ActuralVisit(EmptyStatement_ASTNode *node) override;
void ActuralVisit(DefinitionStatement_ASTNode *node) override;
void ActuralVisit(ExprStatement_ASTNode *node) override;
void ActuralVisit(IfStatement_ASTNode *node) override;
void ActuralVisit(WhileStatement_ASTNode *node) override;
void ActuralVisit(ForStatement_ASTNode *node) override;
void ActuralVisit(JmpStatement_ASTNode *node) override;
void ActuralVisit(SuiteStatement_ASTNode *node) override;
// Expression AST Nodes
void ActuralVisit(NewArrayExpr_ASTNode *node) override;
void ActuralVisit(NewConstructExpr_ASTNode *node) override;
void ActuralVisit(NewExpr_ASTNode *node) override;
void ActuralVisit(AccessExpr_ASTNode *node) override;
void ActuralVisit(IndexExpr_ASTNode *node) override;
void ActuralVisit(SuffixExpr_ASTNode *node) override;
void ActuralVisit(PrefixExpr_ASTNode *node) override;
void ActuralVisit(OppositeExpr_ASTNode *node) override;
void ActuralVisit(LNotExpr_ASTNode *node) override;
void ActuralVisit(BNotExpr_ASTNode *node) override;
void ActuralVisit(MDMExpr_ASTNode *node) override;
void ActuralVisit(PMExpr_ASTNode *node) override;
void ActuralVisit(RLExpr_ASTNode *node) override;
void ActuralVisit(GGLLExpr_ASTNode *node) override;
void ActuralVisit(NEExpr_ASTNode *node) override;
void ActuralVisit(BAndExpr_ASTNode *node) override;
void ActuralVisit(BXorExpr_ASTNode *node) override;
void ActuralVisit(BOrExpr_ASTNode *node) override;
void ActuralVisit(LAndExpr_ASTNode *node) override;
void ActuralVisit(LOrExpr_ASTNode *node) override;
void ActuralVisit(TernaryExpr_ASTNode *node) override;
void ActuralVisit(AssignExpr_ASTNode *node) override;
void ActuralVisit(ThisExpr_ASTNode *node) override;
void ActuralVisit(ParenExpr_ASTNode *node) override;
void ActuralVisit(IDExpr_ASTNode *node) override;
void ActuralVisit(FunctionCallExpr_ASTNode *node) override;
void ActuralVisit(FormattedStringExpr_ASTNode *node) override;
void ActuralVisit(ConstantExpr_ASTNode *node) override;
};
std::shared_ptr<ModuleItem> BuildIR(std::shared_ptr<Program_ASTNode> src);

143
include/IR/IR_basic.h Normal file
View File

@ -0,0 +1,143 @@
#pragma once
#include <ios>
#include <memory>
#include <string>
#include <variant>
#include <vector>
#include "ast/astnode.h"
struct LLVMIRIntType {
size_t bits;
};
struct LLVMIRPTRType {};
struct LLVMIRCLASSTYPE {};
using LLVMType = std::variant<LLVMIRIntType, LLVMIRPTRType, LLVMIRCLASSTYPE>;
class LLVMIRItemBase {
public:
LLVMIRItemBase() = default;
virtual ~LLVMIRItemBase() = default;
virtual void RecursivePrint(std::ostream &os) const;
};
class TypeDefItem : public LLVMIRItemBase {
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class GlobalVarDefItem : public LLVMIRItemBase {
LLVMType type;
std::string name;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class ActionItem : public LLVMIRItemBase {
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class JMPActionItem : public ActionItem {
std::string label;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class BRAction: public JMPActionItem {
std::string cond;
std::string true_label;
std::string false_label;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class UNConditionJMPAction: public JMPActionItem {
std::string label;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class RETAction : public JMPActionItem {
std::string value;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class BinaryOperationAction : public ActionItem {
std::string op;
std::string lhs;
std::string rhs;
std::string result;
LLVMType type;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class AllocaAction : public ActionItem {
std::string name;
LLVMType type;
size_t num;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class LoadAction : public ActionItem {
std::string result;
LLVMType ty;
std::string ptr;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class StoreAction : public ActionItem {
LLVMType ty;
std::string value;
std::string ptr;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class GetElementPtrAction : public ActionItem {
std::string result;
LLVMType ty;
std::string ptr;
std::vector<std::string> indices;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class ICMPAction : public ActionItem {
std::string op;
std::string lhs;
std::string rhs;
std::string result;
LLVMType ty;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class BlockItem : public LLVMIRItemBase {
std::string label;
std::vector<std::shared_ptr<ActionItem>> actions;
std::shared_ptr<JMPActionItem> exit_action;
public:
void RecursivePrint(std::ostream &os) const { ; }
};
class FunctionDefItem : public LLVMIRItemBase {
std::vector<std::shared_ptr<BlockItem>> basic_blocks;
public:
void RecursivePrint(std::ostream &os) const {
for (auto &item : basic_blocks) {
item->RecursivePrint(os);
os << '\n';
}
}
};
class ModuleItem : public LLVMIRItemBase {
std::vector<std::shared_ptr<TypeDefItem>> type_defs;
std::vector<std::shared_ptr<GlobalVarDefItem>> global_var_defs;
std::vector<std::shared_ptr<FunctionDefItem>> function_defs;
public:
void RecursivePrint(std::ostream &os) const {
for (auto &item : type_defs) {
item->RecursivePrint(os);
os << '\n';
}
for (auto &item : global_var_defs) {
item->RecursivePrint(os);
os << '\n';
}
for (auto &item : function_defs) {
item->RecursivePrint(os);
os << '\n';
}
}
};

View File

@ -2,6 +2,7 @@
#define AST_H #define AST_H
#include "astnode.h" #include "astnode.h"
#include "astnode_visitor.h" #include "astnode_visitor.h"
#include "semantic_visitor.h"
#include "expr_astnode.h" #include "expr_astnode.h"
#include "statement_astnode.h" #include "statement_astnode.h"
#include "structural_astnode.h" #include "structural_astnode.h"

View File

@ -54,67 +54,4 @@ class ASTNodeVirturalVisitor : public ASTNodeVisitorBase {
virtual void ActuralVisit(ConstantExpr_ASTNode *node) = 0; virtual void ActuralVisit(ConstantExpr_ASTNode *node) = 0;
}; };
class ASTSemanticCheckVisitor : public ASTNodeVirturalVisitor {
bool is_in_func_def;
bool has_return;
FunctionSchema cur_func_schema;
std::string cur_class_name;
bool is_in_class_def;
size_t loop_level;
std::shared_ptr<GlobalScope> global_scope;
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
bool ClassExists(const std::string &name) {
if (name == "int" || name == "bool") return true;
return global_scope->classes.find(name) != global_scope->classes.end();
}
public:
ASTSemanticCheckVisitor() : is_in_func_def(false), loop_level(0) {}
// Structural AST Nodes
void ActuralVisit(FuncDef_ASTNode *node) override;
void ActuralVisit(ClassDef_ASTNode *node) override;
void ActuralVisit(Program_ASTNode *node) override;
// Statement AST Nodes
void ActuralVisit(EmptyStatement_ASTNode *node) override;
void ActuralVisit(DefinitionStatement_ASTNode *node) override;
void ActuralVisit(ExprStatement_ASTNode *node) override;
void ActuralVisit(IfStatement_ASTNode *node) override;
void ActuralVisit(WhileStatement_ASTNode *node) override;
void ActuralVisit(ForStatement_ASTNode *node) override;
void ActuralVisit(JmpStatement_ASTNode *node) override;
void ActuralVisit(SuiteStatement_ASTNode *node) override;
// Expression AST Nodes
void ActuralVisit(NewArrayExpr_ASTNode *node) override;
void ActuralVisit(NewConstructExpr_ASTNode *node) override;
void ActuralVisit(NewExpr_ASTNode *node) override;
void ActuralVisit(AccessExpr_ASTNode *node) override;
void ActuralVisit(IndexExpr_ASTNode *node) override;
void ActuralVisit(SuffixExpr_ASTNode *node) override;
void ActuralVisit(PrefixExpr_ASTNode *node) override;
void ActuralVisit(OppositeExpr_ASTNode *node) override;
void ActuralVisit(LNotExpr_ASTNode *node) override;
void ActuralVisit(BNotExpr_ASTNode *node) override;
void ActuralVisit(MDMExpr_ASTNode *node) override;
void ActuralVisit(PMExpr_ASTNode *node) override;
void ActuralVisit(RLExpr_ASTNode *node) override;
void ActuralVisit(GGLLExpr_ASTNode *node) override;
void ActuralVisit(NEExpr_ASTNode *node) override;
void ActuralVisit(BAndExpr_ASTNode *node) override;
void ActuralVisit(BXorExpr_ASTNode *node) override;
void ActuralVisit(BOrExpr_ASTNode *node) override;
void ActuralVisit(LAndExpr_ASTNode *node) override;
void ActuralVisit(LOrExpr_ASTNode *node) override;
void ActuralVisit(TernaryExpr_ASTNode *node) override;
void ActuralVisit(AssignExpr_ASTNode *node) override;
void ActuralVisit(ThisExpr_ASTNode *node) override;
void ActuralVisit(ParenExpr_ASTNode *node) override;
void ActuralVisit(IDExpr_ASTNode *node) override;
void ActuralVisit(FunctionCallExpr_ASTNode *node) override;
void ActuralVisit(FormattedStringExpr_ASTNode *node) override;
void ActuralVisit(ConstantExpr_ASTNode *node) override;
};
#endif // ASTNODE_ActuralVisitOR_H #endif // ASTNODE_ActuralVisitOR_H

View File

@ -17,6 +17,7 @@ class ScopeBase {
protected: protected:
ScopeBase *parent; // cannot use std::shared_ptr<ScopeBase> because of circular dependency ScopeBase *parent; // cannot use std::shared_ptr<ScopeBase> because of circular dependency
size_t scope_id;
virtual bool VariableNameAvailable(const std::string &name, int ttl) = 0; virtual bool VariableNameAvailable(const std::string &name, int ttl) = 0;
virtual bool add_variable(const std::string &name, const ExprTypeInfo &type) = 0; virtual bool add_variable(const std::string &name, const ExprTypeInfo &type) = 0;
virtual ExprTypeInfo fetch_varaible(const std::string &name) = 0; virtual ExprTypeInfo fetch_varaible(const std::string &name) = 0;
@ -26,6 +27,11 @@ class ScopeBase {
"for", "while", "break", "continue", "return"}; "for", "while", "break", "continue", "return"};
return keywords.find(name) != keywords.end(); return keywords.find(name) != keywords.end();
} }
public:
ScopeBase() {
static size_t scope_counter=0;
scope_id = scope_counter++;
}
}; };
class LocalScope : public ScopeBase { class LocalScope : public ScopeBase {
friend class Visitor; friend class Visitor;
@ -104,6 +110,7 @@ class ClassDefScope : public ScopeBase {
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src); friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
std::unordered_map<std::string, ExprTypeInfo> member_variables; std::unordered_map<std::string, ExprTypeInfo> member_variables;
std::unordered_map<std::string, std::shared_ptr<FunctionScope>> member_functions; std::unordered_map<std::string, std::shared_ptr<FunctionScope>> member_functions;
IRClassInfo llvm_class_info;
bool add_variable(const std::string &name, const ExprTypeInfo &type) override { bool add_variable(const std::string &name, const ExprTypeInfo &type) override {
if (!VariableNameAvailable(name, 0)) { if (!VariableNameAvailable(name, 0)) {
return false; return false;

View File

@ -0,0 +1,69 @@
#pragma once
#include "astnode.h"
#include "expr_astnode.h"
#include "statement_astnode.h"
#include "structural_astnode.h"
#include "astnode_visitor.h"
class ASTSemanticCheckVisitor : public ASTNodeVirturalVisitor {
bool is_in_func_def;
bool has_return;
FunctionSchema cur_func_schema;
std::string cur_class_name;
bool is_in_class_def;
size_t loop_level;
std::shared_ptr<GlobalScope> global_scope;
friend std::shared_ptr<Program_ASTNode> CheckAndDecorate(std::shared_ptr<Program_ASTNode> src);
bool ClassExists(const std::string &name) {
if (name == "int" || name == "bool") return true;
return global_scope->classes.find(name) != global_scope->classes.end();
}
public:
ASTSemanticCheckVisitor() : is_in_func_def(false), loop_level(0) {}
// Structural AST Nodes
void ActuralVisit(FuncDef_ASTNode *node) override;
void ActuralVisit(ClassDef_ASTNode *node) override;
void ActuralVisit(Program_ASTNode *node) override;
// Statement AST Nodes
void ActuralVisit(EmptyStatement_ASTNode *node) override;
void ActuralVisit(DefinitionStatement_ASTNode *node) override;
void ActuralVisit(ExprStatement_ASTNode *node) override;
void ActuralVisit(IfStatement_ASTNode *node) override;
void ActuralVisit(WhileStatement_ASTNode *node) override;
void ActuralVisit(ForStatement_ASTNode *node) override;
void ActuralVisit(JmpStatement_ASTNode *node) override;
void ActuralVisit(SuiteStatement_ASTNode *node) override;
// Expression AST Nodes
void ActuralVisit(NewArrayExpr_ASTNode *node) override;
void ActuralVisit(NewConstructExpr_ASTNode *node) override;
void ActuralVisit(NewExpr_ASTNode *node) override;
void ActuralVisit(AccessExpr_ASTNode *node) override;
void ActuralVisit(IndexExpr_ASTNode *node) override;
void ActuralVisit(SuffixExpr_ASTNode *node) override;
void ActuralVisit(PrefixExpr_ASTNode *node) override;
void ActuralVisit(OppositeExpr_ASTNode *node) override;
void ActuralVisit(LNotExpr_ASTNode *node) override;
void ActuralVisit(BNotExpr_ASTNode *node) override;
void ActuralVisit(MDMExpr_ASTNode *node) override;
void ActuralVisit(PMExpr_ASTNode *node) override;
void ActuralVisit(RLExpr_ASTNode *node) override;
void ActuralVisit(GGLLExpr_ASTNode *node) override;
void ActuralVisit(NEExpr_ASTNode *node) override;
void ActuralVisit(BAndExpr_ASTNode *node) override;
void ActuralVisit(BXorExpr_ASTNode *node) override;
void ActuralVisit(BOrExpr_ASTNode *node) override;
void ActuralVisit(LAndExpr_ASTNode *node) override;
void ActuralVisit(LOrExpr_ASTNode *node) override;
void ActuralVisit(TernaryExpr_ASTNode *node) override;
void ActuralVisit(AssignExpr_ASTNode *node) override;
void ActuralVisit(ThisExpr_ASTNode *node) override;
void ActuralVisit(ParenExpr_ASTNode *node) override;
void ActuralVisit(IDExpr_ASTNode *node) override;
void ActuralVisit(FunctionCallExpr_ASTNode *node) override;
void ActuralVisit(FormattedStringExpr_ASTNode *node) override;
void ActuralVisit(ConstantExpr_ASTNode *node) override;
};

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <stdexcept> #include <stdexcept>
#include <unordered_map>
#include <variant> #include <variant>
#include <vector>
enum class ASTNodeType { enum class ASTNodeType {
// Expression nodes // Expression nodes
NewArrayExpr, NewArrayExpr,
@ -99,3 +101,37 @@ inline bool operator==(const ExprTypeInfo &l, const ExprTypeInfo &r) {
throw std::runtime_error("something strange happened"); throw std::runtime_error("something strange happened");
} }
inline bool operator!=(const ExprTypeInfo &l, const ExprTypeInfo &r) { return !(l == r); } inline bool operator!=(const ExprTypeInfo &l, const ExprTypeInfo &r) { return !(l == r); }
class IRClassInfo {
public:
std::string class_name; // This data must be provided by user
std::vector<size_t> member_var_size; // This data must be provided by user. Each of them is the size of a member
// variable, which must be in [1,4]
std::unordered_map<std::string, size_t> member_var_offset; // This data must be provided by user
std::vector<size_t> member_var_pos_after_align;
size_t class_size_after_align;
void ArrangeSpace() {
size_t cur_pos = 0;
size_t align_size = 1;
for (size_t cur_size : member_var_size) {
if (cur_size != 1 && cur_size != 4) throw std::runtime_error("Invalid member variable size");
if (cur_pos % cur_size == 0) {
member_var_pos_after_align.push_back(cur_pos);
cur_pos += cur_size;
} else {
cur_pos += cur_size - (cur_pos % cur_size);
member_var_pos_after_align.push_back(cur_pos);
cur_pos += cur_size;
}
if (cur_size > align_size) align_size = cur_size;
if (cur_pos % align_size != 0) cur_pos += align_size - (cur_pos % align_size);
class_size_after_align = cur_pos;
}
}
};
class IRVariableInfo {
public:
enum class VariableType { global_variable, local_variable, member_variable };
std::string class_name;
std::string variable_name;
};

View File

@ -1,7 +1,8 @@
add_subdirectory(ast) add_subdirectory(ast)
add_subdirectory(semantic) add_subdirectory(semantic)
add_subdirectory(IR)
add_executable(zmxcc main.cpp) add_executable(zmxcc main.cpp)
target_link_libraries(zmxcc semantic argparse) target_link_libraries(zmxcc semantic argparse IR)
set_target_properties(zmxcc PROPERTIES set_target_properties(zmxcc PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
) )

5
src/IR/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
include_directories(${CMAKE_SOURCE_DIR}/include/IR)
file(GLOB IR_SOURCES "*.cpp")
add_library(IR STATIC ${IR_SOURCES})
target_link_libraries(IR PUBLIC ast)

167
src/IR/IRBuilder.cpp Normal file
View File

@ -0,0 +1,167 @@
#include "IRBuilder.h"
#include <stdexcept>
// Structural AST Nodes
void IRBuilder::ActuralVisit(FuncDef_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(ClassDef_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(Program_ASTNode *node) {
// TODO: Implement function body
throw std::runtime_error("IRBuilder not implemented");
}
// Statement AST Nodes
void IRBuilder::ActuralVisit(EmptyStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(DefinitionStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(ExprStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(IfStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(WhileStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(ForStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(JmpStatement_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(SuiteStatement_ASTNode *node) {
// TODO: Implement function body
}
// Expression AST Nodes
void IRBuilder::ActuralVisit(NewArrayExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(NewConstructExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(NewExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(AccessExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(IndexExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(SuffixExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(PrefixExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(OppositeExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(LNotExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(BNotExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(MDMExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(PMExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(RLExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(GGLLExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(NEExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(BAndExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(BXorExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(BOrExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(LAndExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(LOrExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(TernaryExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(AssignExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(ThisExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(ParenExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(IDExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(FunctionCallExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(FormattedStringExpr_ASTNode *node) {
// TODO: Implement function body
}
void IRBuilder::ActuralVisit(ConstantExpr_ASTNode *node) {
// TODO: Implement function body
}
std::shared_ptr<ModuleItem> BuildIR(std::shared_ptr<Program_ASTNode> src) {
IRBuilder visitor;
visitor.visit(src.get());
}

10
src/IR/build.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
# Get the directory of the script
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# Change to the script directory
cd "$SCRIPT_DIR"
clang-18 -S -emit-llvm --target=riscv32-unknown-elf -O2 -fno-builtin-printf -fno-builtin-memcpy \
builtin.c -o builtin_intermediate.ll
sed 's/_builtin_/.builtin./g;s/string_/string./g;s/array_/array./g' builtin_intermediate.ll > builtin.ll
rm builtin_intermediate.ll
llc-18 -march=riscv32 builtin.ll -o builtin.s -O2

130
src/IR/builtin.c Normal file
View File

@ -0,0 +1,130 @@
#include <stdarg.h>
#define bool _Bool
#define EOF (-1)
// libc function
void* malloc(unsigned int size);
void free(void* ptr);
int printf(const char *pattern, ...);
int scanf(const char *format, ...);
int sprintf(char *str, const char *pattern, ...);
int sscanf(const char *str, const char *pattern, ...);
int string_length(char *self) {
int res=0;
while(self[res]!='\0') {
res++;
}
return res;
}
char* string_substring(char *self,int left, int right) {
int len = right - left;
char *res = (char*)malloc(len+1);
for(int i=0;i<len;i++) {
res[i] = self[left+i];
}
res[len] = '\0';
return res;
}
int string_parseInt(char *self) {
int res;
sscanf(self, "%d", &res);
return res;
}
int string_ord(char *self, int index) {
return self[index];
}
void print(char *str) {
printf("%s", str);
}
void println(char *str) {
printf("%s\n", str);
}
void printInt(int n) {
printf("%d", n);
}
void printlnInt(int n) {
printf("%d\n", n);
}
char* toString(int n) {
char *res = (char*)malloc(15);
sprintf(res, "%d", n);
return res;
}
char* getString() { // same as getline
char *res=(char*)malloc(11);
int allocated_length = 10;
int cur_length = 0;
char ch;
while(scanf("%c",&ch)==1) {
if(ch=='\n'||ch=='\r') break;
if(cur_length==allocated_length) {
char *new_res = (char*)malloc(allocated_length*2+1);
for(int i=0;i<allocated_length;i++) {
new_res[i] = res[i];
}
free(res);
res = new_res;
allocated_length *= 2;
}
res[cur_length++] = ch;
}
res[cur_length] = '\0';
return res;
}
int getInt() {
int res;
scanf("%d", &res);
return res;
}
void* _builtin_AllocateClassBody(int size) {
return malloc(size);
}
int _builtin_GetArrayLength(void* array) {
int res=0;
array=((char*)array)-4;
res|=(((unsigned char*)array)[0]);
res|=((unsigned int)(((unsigned char*)array)[1])<<8);
res|=((unsigned int)(((unsigned char*)array)[2])<<16);
res|=((unsigned int)(((unsigned char*)array)[3])<<24);
return res;
}
void* _builtin_RecursiveAllocateArray(int dims_with_size, int element_size, int* dim_size) {
void* res;
if(dims_with_size==1) {
res=malloc(dim_size[0]*element_size+4);
((unsigned char*)res)[0] = dim_size[0]&0xff;
((unsigned char*)res)[1] = (dim_size[0]>>8)&0xff;
((unsigned char*)res)[2] = (dim_size[0]>>16)&0xff;
((unsigned char*)res)[3] = (dim_size[0]>>24)&0xff;
void* actual_space=((char*)res)+4;
res=actual_space;
} else {
res=malloc(dim_size[0]*sizeof(void*)+4);
((unsigned char*)res)[0] = dim_size[0]&0xff;
((unsigned char*)res)[1] = (dim_size[0]>>8)&0xff;
((unsigned char*)res)[2] = (dim_size[0]>>16)&0xff;
((unsigned char*)res)[3] = (dim_size[0]>>24)&0xff;
void* actual_space=((char*)res)+4;
for(int i=0;i<dim_size[0];i++) {
((void**)actual_space)[i] = _builtin_RecursiveAllocateArray(dims_with_size-1, element_size, dim_size+1);
}
res=actual_space;
}
return res;
}
// void* _builtin_AllocateArray(int total_dimensions,int basic_element_size,...) {
// va_list args;
// va_start(args, basic_element_size);
// int* dim_size=(int*)malloc(total_dimensions*sizeof(int));
// int dims_with_size=0;
// for(int i=0;i<total_dimensions;i++) {
// dim_size[i] = va_arg(args, int);
// if(dim_size[i]>=0) dims_with_size++;
// }
// if(dims_with_size<total_dimensions) basic_element_size = sizeof(void*);
// va_end(args);
// void* res=_builtin_RecursiveAllocateArray(dims_with_size, basic_element_size, dim_size);
// free(dim_size);
// return res;
// }

327
src/IR/builtin.ll Normal file
View File

@ -0,0 +1,327 @@
; ModuleID = 'builtin.c'
source_filename = "builtin.c"
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
target triple = "riscv32-unknown-unknown-elf"
@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
@.str.1 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
@.str.2 = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
@.str.3 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@.str.4 = private unnamed_addr constant [3 x i8] c"%c\00", align 1
; Function Attrs: nofree norecurse nosync nounwind memory(argmem: read)
define dso_local i32 @string.length(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
br label %2
2: ; preds = %2, %1
%3 = phi i32 [ 0, %1 ], [ %7, %2 ]
%4 = getelementptr inbounds i8, ptr %0, i32 %3
%5 = load i8, ptr %4, align 1, !tbaa !6
%6 = icmp eq i8 %5, 0
%7 = add nuw nsw i32 %3, 1
br i1 %6, label %8, label %2, !llvm.loop !9
8: ; preds = %2
ret i32 %3
}
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
; Function Attrs: nofree nounwind memory(write, argmem: read, inaccessiblemem: readwrite)
define dso_local noalias noundef ptr @string.substring(ptr nocapture noundef readonly %0, i32 noundef %1, i32 noundef %2) local_unnamed_addr #2 {
%4 = sub nsw i32 %2, %1
%5 = add nsw i32 %4, 1
%6 = tail call ptr @malloc(i32 noundef %5) #10
%7 = getelementptr i8, ptr %0, i32 %1
%8 = icmp sgt i32 %4, 0
br i1 %8, label %11, label %9
9: ; preds = %11, %3
%10 = getelementptr inbounds i8, ptr %6, i32 %4
store i8 0, ptr %10, align 1, !tbaa !6
ret ptr %6
11: ; preds = %3, %11
%12 = phi i32 [ %16, %11 ], [ 0, %3 ]
%13 = getelementptr i8, ptr %7, i32 %12
%14 = load i8, ptr %13, align 1, !tbaa !6
%15 = getelementptr inbounds i8, ptr %6, i32 %12
store i8 %14, ptr %15, align 1, !tbaa !6
%16 = add nuw nsw i32 %12, 1
%17 = icmp eq i32 %16, %4
br i1 %17, label %9, label %11, !llvm.loop !11
}
; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
declare dso_local noalias noundef ptr @malloc(i32 noundef) local_unnamed_addr #3
; Function Attrs: nofree nounwind
define dso_local i32 @string.parseInt(ptr nocapture noundef readonly %0) local_unnamed_addr #4 {
%2 = alloca i32, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %2) #11
%3 = call i32 (ptr, ptr, ...) @sscanf(ptr noundef %0, ptr noundef nonnull @.str, ptr noundef nonnull %2) #12
%4 = load i32, ptr %2, align 4, !tbaa !12
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %2) #11
ret i32 %4
}
; Function Attrs: nofree nounwind
declare dso_local noundef i32 @sscanf(ptr nocapture noundef readonly, ptr nocapture noundef readonly, ...) local_unnamed_addr #4
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
define dso_local i32 @string.ord(ptr nocapture noundef readonly %0, i32 noundef %1) local_unnamed_addr #5 {
%3 = getelementptr inbounds i8, ptr %0, i32 %1
%4 = load i8, ptr %3, align 1, !tbaa !6
%5 = zext i8 %4 to i32
ret i32 %5
}
; Function Attrs: nounwind
define dso_local void @print(ptr noundef %0) local_unnamed_addr #6 {
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str.1, ptr noundef %0) #13
ret void
}
declare dso_local i32 @printf(ptr noundef, ...) local_unnamed_addr #7
; Function Attrs: nounwind
define dso_local void @println(ptr noundef %0) local_unnamed_addr #6 {
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str.2, ptr noundef %0) #13
ret void
}
; Function Attrs: nounwind
define dso_local void @printInt(i32 noundef %0) local_unnamed_addr #6 {
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str, i32 noundef %0) #13
ret void
}
; Function Attrs: nounwind
define dso_local void @printlnInt(i32 noundef %0) local_unnamed_addr #6 {
%2 = tail call i32 (ptr, ...) @printf(ptr noundef nonnull @.str.3, i32 noundef %0) #13
ret void
}
; Function Attrs: nofree nounwind
define dso_local noalias noundef ptr @toString(i32 noundef %0) local_unnamed_addr #4 {
%2 = tail call dereferenceable_or_null(15) ptr @malloc(i32 noundef 15) #10
%3 = tail call i32 (ptr, ptr, ...) @sprintf(ptr noundef nonnull dereferenceable(1) %2, ptr noundef nonnull dereferenceable(1) @.str, i32 noundef %0) #12
ret ptr %2
}
; Function Attrs: nofree nounwind
declare dso_local noundef i32 @sprintf(ptr noalias nocapture noundef writeonly, ptr nocapture noundef readonly, ...) local_unnamed_addr #4
; Function Attrs: nounwind
define dso_local noalias ptr @getString() local_unnamed_addr #6 {
%1 = alloca i8, align 1
%2 = tail call dereferenceable_or_null(11) ptr @malloc(i32 noundef 11) #10
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %1) #11
%3 = call i32 (ptr, ...) @scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %1) #12
%4 = icmp eq i32 %3, 1
br i1 %4, label %5, label %34
5: ; preds = %0, %26
%6 = phi ptr [ %29, %26 ], [ %2, %0 ]
%7 = phi i32 [ %30, %26 ], [ 0, %0 ]
%8 = phi i32 [ %28, %26 ], [ 10, %0 ]
%9 = load i8, ptr %1, align 1
switch i8 %9, label %10 [
i8 13, label %34
i8 10, label %34
]
10: ; preds = %5
%11 = icmp eq i32 %7, %8
br i1 %11, label %12, label %26
12: ; preds = %10
%13 = shl nuw nsw i32 %7, 1
%14 = or disjoint i32 %13, 1
%15 = call ptr @malloc(i32 noundef %14) #10
%16 = icmp eq i32 %7, 0
br i1 %16, label %17, label %19
17: ; preds = %19, %12
call void @free(ptr noundef %6) #12
%18 = load i8, ptr %1, align 1, !tbaa !6
br label %26
19: ; preds = %12, %19
%20 = phi i32 [ %24, %19 ], [ 0, %12 ]
%21 = getelementptr inbounds i8, ptr %6, i32 %20
%22 = load i8, ptr %21, align 1, !tbaa !6
%23 = getelementptr inbounds i8, ptr %15, i32 %20
store i8 %22, ptr %23, align 1, !tbaa !6
%24 = add nuw nsw i32 %20, 1
%25 = icmp eq i32 %24, %7
br i1 %25, label %17, label %19, !llvm.loop !14
26: ; preds = %17, %10
%27 = phi i8 [ %18, %17 ], [ %9, %10 ]
%28 = phi i32 [ %13, %17 ], [ %8, %10 ]
%29 = phi ptr [ %15, %17 ], [ %6, %10 ]
%30 = add nuw nsw i32 %7, 1
%31 = getelementptr inbounds i8, ptr %29, i32 %7
store i8 %27, ptr %31, align 1, !tbaa !6
%32 = call i32 (ptr, ...) @scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %1) #12
%33 = icmp eq i32 %32, 1
br i1 %33, label %5, label %34, !llvm.loop !15
34: ; preds = %26, %5, %5, %0
%35 = phi i32 [ 0, %0 ], [ %7, %5 ], [ %7, %5 ], [ %30, %26 ]
%36 = phi ptr [ %2, %0 ], [ %6, %5 ], [ %6, %5 ], [ %29, %26 ]
%37 = getelementptr inbounds i8, ptr %36, i32 %35
store i8 0, ptr %37, align 1, !tbaa !6
call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %1) #11
ret ptr %36
}
; Function Attrs: nofree nounwind
declare dso_local noundef i32 @scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
; Function Attrs: mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite)
declare dso_local void @free(ptr allocptr nocapture noundef) local_unnamed_addr #8
; Function Attrs: nofree nounwind
define dso_local i32 @getInt() local_unnamed_addr #4 {
%1 = alloca i32, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %1) #11
%2 = call i32 (ptr, ...) @scanf(ptr noundef nonnull @.str, ptr noundef nonnull %1) #12
%3 = load i32, ptr %1, align 4, !tbaa !12
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %1) #11
ret i32 %3
}
; Function Attrs: mustprogress nofree nounwind willreturn memory(inaccessiblemem: readwrite)
define dso_local noalias noundef ptr @.builtin.AllocateClassBody(i32 noundef %0) local_unnamed_addr #9 {
%2 = tail call ptr @malloc(i32 noundef %0) #10
ret ptr %2
}
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
define dso_local i32 @.builtin.GetArrayLength(ptr nocapture noundef readonly %0) local_unnamed_addr #5 {
%2 = getelementptr inbounds i8, ptr %0, i32 -4
%3 = load i8, ptr %2, align 1, !tbaa !6
%4 = zext i8 %3 to i32
%5 = getelementptr inbounds i8, ptr %0, i32 -3
%6 = load i8, ptr %5, align 1, !tbaa !6
%7 = zext i8 %6 to i32
%8 = shl nuw nsw i32 %7, 8
%9 = or disjoint i32 %8, %4
%10 = getelementptr inbounds i8, ptr %0, i32 -2
%11 = load i8, ptr %10, align 1, !tbaa !6
%12 = zext i8 %11 to i32
%13 = shl nuw nsw i32 %12, 16
%14 = or disjoint i32 %9, %13
%15 = getelementptr inbounds i8, ptr %0, i32 -1
%16 = load i8, ptr %15, align 1, !tbaa !6
%17 = zext i8 %16 to i32
%18 = shl nuw i32 %17, 24
%19 = or disjoint i32 %14, %18
ret i32 %19
}
; Function Attrs: nofree nounwind memory(write, argmem: read, inaccessiblemem: readwrite)
define dso_local noalias nonnull ptr @.builtin.RecursiveAllocateArray(i32 noundef %0, i32 noundef %1, ptr nocapture noundef readonly %2) local_unnamed_addr #2 {
%4 = icmp eq i32 %0, 1
%5 = load i32, ptr %2, align 4, !tbaa !12
%6 = trunc i32 %5 to i8
%7 = lshr i32 %5, 8
%8 = trunc i32 %7 to i8
%9 = lshr i32 %5, 16
%10 = trunc i32 %9 to i8
%11 = lshr i32 %5, 24
%12 = trunc i32 %11 to i8
br i1 %4, label %13, label %21
13: ; preds = %3
%14 = mul nsw i32 %5, %1
%15 = add nsw i32 %14, 4
%16 = tail call ptr @malloc(i32 noundef %15) #10
store i8 %6, ptr %16, align 1, !tbaa !6
%17 = getelementptr inbounds i8, ptr %16, i32 1
store i8 %8, ptr %17, align 1, !tbaa !6
%18 = getelementptr inbounds i8, ptr %16, i32 2
store i8 %10, ptr %18, align 1, !tbaa !6
%19 = getelementptr inbounds i8, ptr %16, i32 3
store i8 %12, ptr %19, align 1, !tbaa !6
%20 = getelementptr inbounds i8, ptr %16, i32 4
br label %40
21: ; preds = %3
%22 = shl i32 %5, 2
%23 = add i32 %22, 4
%24 = tail call ptr @malloc(i32 noundef %23) #10
store i8 %6, ptr %24, align 1, !tbaa !6
%25 = getelementptr inbounds i8, ptr %24, i32 1
store i8 %8, ptr %25, align 1, !tbaa !6
%26 = getelementptr inbounds i8, ptr %24, i32 2
store i8 %10, ptr %26, align 1, !tbaa !6
%27 = getelementptr inbounds i8, ptr %24, i32 3
store i8 %12, ptr %27, align 1, !tbaa !6
%28 = getelementptr inbounds i8, ptr %24, i32 4
%29 = icmp sgt i32 %5, 0
br i1 %29, label %30, label %40
30: ; preds = %21
%31 = add nsw i32 %0, -1
%32 = getelementptr inbounds i32, ptr %2, i32 1
br label %33
33: ; preds = %30, %33
%34 = phi i32 [ 0, %30 ], [ %37, %33 ]
%35 = tail call ptr @.builtin.RecursiveAllocateArray(i32 noundef %31, i32 noundef %1, ptr noundef nonnull %32) #12
%36 = getelementptr inbounds ptr, ptr %28, i32 %34
store ptr %35, ptr %36, align 4, !tbaa !16
%37 = add nuw nsw i32 %34, 1
%38 = load i32, ptr %2, align 4, !tbaa !12
%39 = icmp slt i32 %37, %38
br i1 %39, label %33, label %40, !llvm.loop !18
40: ; preds = %33, %21, %13
%41 = phi ptr [ %20, %13 ], [ %28, %21 ], [ %28, %33 ]
ret ptr %41
}
attributes #0 = { nofree norecurse nosync nounwind memory(argmem: read) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { nofree nounwind memory(write, argmem: read, inaccessiblemem: readwrite) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #3 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #4 = { nofree nounwind "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #5 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #6 = { nounwind "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #7 = { "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #8 = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #9 = { mustprogress nofree nounwind willreturn memory(inaccessiblemem: readwrite) "no-builtin-memcpy" "no-builtin-printf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic-rv32" "target-features"="+32bit,+a,+c,+m,+relax,-d,-e,-experimental-zacas,-experimental-zcmop,-experimental-zfbfmin,-experimental-zicfilp,-experimental-zicfiss,-experimental-zimop,-experimental-ztso,-experimental-zvfbfmin,-experimental-zvfbfwma,-f,-h,-smaia,-smepmp,-ssaia,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-za128rs,-za64rs,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfa,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #10 = { allocsize(0) "no-builtin-memcpy" "no-builtin-printf" }
attributes #11 = { nounwind }
attributes #12 = { "no-builtin-memcpy" "no-builtin-printf" }
attributes #13 = { nobuiltin nounwind "no-builtin-memcpy" "no-builtin-printf" }
!llvm.module.flags = !{!0, !1, !2, !4}
!llvm.ident = !{!5}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"target-abi", !"ilp32"}
!2 = !{i32 6, !"riscv-isa", !3}
!3 = !{!"rv32i2p1_m2p0_a2p1_c2p0"}
!4 = !{i32 8, !"SmallDataLimit", i32 8}
!5 = !{!"Ubuntu clang version 18.1.8 (++20240731024944+3b5b5c1ec4a3-1~exp1~20240731145000.144)"}
!6 = !{!7, !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
!9 = distinct !{!9, !10}
!10 = !{!"llvm.loop.mustprogress"}
!11 = distinct !{!11, !10}
!12 = !{!13, !13, i64 0}
!13 = !{!"int", !7, i64 0}
!14 = distinct !{!14, !10}
!15 = distinct !{!15, !10}
!16 = !{!17, !17, i64 0}
!17 = !{!"any pointer", !7, i64 0}
!18 = distinct !{!18, !10}

464
src/IR/builtin.s Normal file
View File

@ -0,0 +1,464 @@
.text
.attribute 4, 16
.attribute 5, "rv32i2p1_m2p0_a2p1_c2p0"
.file "builtin.c"
.option push
.option arch, +a, +c, +m
.globl string.length # -- Begin function string.length
.p2align 1
.type string.length,@function
string.length: # @string.length
# %bb.0:
li a1, 0
.LBB0_1: # =>This Inner Loop Header: Depth=1
add a2, a0, a1
lbu a2, 0(a2)
addi a1, a1, 1
bnez a2, .LBB0_1
# %bb.2:
addi a0, a1, -1
ret
.Lfunc_end0:
.size string.length, .Lfunc_end0-string.length
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl string.substring # -- Begin function string.substring
.p2align 1
.type string.substring,@function
string.substring: # @string.substring
# %bb.0:
addi sp, sp, -16
sw ra, 12(sp) # 4-byte Folded Spill
sw s0, 8(sp) # 4-byte Folded Spill
sw s1, 4(sp) # 4-byte Folded Spill
sw s2, 0(sp) # 4-byte Folded Spill
mv s0, a1
mv s2, a0
sub s1, a2, a1
addi a0, s1, 1
call malloc
add a1, a0, s1
blez s1, .LBB1_3
# %bb.1: # %.preheader
add s0, s0, s2
mv a2, a0
.LBB1_2: # =>This Inner Loop Header: Depth=1
lbu a3, 0(s0)
sb a3, 0(a2)
addi a2, a2, 1
addi s0, s0, 1
bne a2, a1, .LBB1_2
.LBB1_3:
sb zero, 0(a1)
lw ra, 12(sp) # 4-byte Folded Reload
lw s0, 8(sp) # 4-byte Folded Reload
lw s1, 4(sp) # 4-byte Folded Reload
lw s2, 0(sp) # 4-byte Folded Reload
addi sp, sp, 16
ret
.Lfunc_end1:
.size string.substring, .Lfunc_end1-string.substring
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl string.parseInt # -- Begin function string.parseInt
.p2align 1
.type string.parseInt,@function
string.parseInt: # @string.parseInt
# %bb.0:
addi sp, sp, -16
sw ra, 12(sp) # 4-byte Folded Spill
lui a1, %hi(.L.str)
addi a1, a1, %lo(.L.str)
addi a2, sp, 8
call sscanf
lw a0, 8(sp)
lw ra, 12(sp) # 4-byte Folded Reload
addi sp, sp, 16
ret
.Lfunc_end2:
.size string.parseInt, .Lfunc_end2-string.parseInt
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl string.ord # -- Begin function string.ord
.p2align 1
.type string.ord,@function
string.ord: # @string.ord
# %bb.0:
add a0, a0, a1
lbu a0, 0(a0)
ret
.Lfunc_end3:
.size string.ord, .Lfunc_end3-string.ord
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl print # -- Begin function print
.p2align 1
.type print,@function
print: # @print
# %bb.0:
lui a1, %hi(.L.str.1)
addi a1, a1, %lo(.L.str.1)
mv a2, a0
mv a0, a1
mv a1, a2
tail printf
.Lfunc_end4:
.size print, .Lfunc_end4-print
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl println # -- Begin function println
.p2align 1
.type println,@function
println: # @println
# %bb.0:
lui a1, %hi(.L.str.2)
addi a1, a1, %lo(.L.str.2)
mv a2, a0
mv a0, a1
mv a1, a2
tail printf
.Lfunc_end5:
.size println, .Lfunc_end5-println
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl printInt # -- Begin function printInt
.p2align 1
.type printInt,@function
printInt: # @printInt
# %bb.0:
lui a1, %hi(.L.str)
addi a1, a1, %lo(.L.str)
mv a2, a0
mv a0, a1
mv a1, a2
tail printf
.Lfunc_end6:
.size printInt, .Lfunc_end6-printInt
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl printlnInt # -- Begin function printlnInt
.p2align 1
.type printlnInt,@function
printlnInt: # @printlnInt
# %bb.0:
lui a1, %hi(.L.str.3)
addi a1, a1, %lo(.L.str.3)
mv a2, a0
mv a0, a1
mv a1, a2
tail printf
.Lfunc_end7:
.size printlnInt, .Lfunc_end7-printlnInt
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl toString # -- Begin function toString
.p2align 1
.type toString,@function
toString: # @toString
# %bb.0:
addi sp, sp, -16
sw ra, 12(sp) # 4-byte Folded Spill
sw s0, 8(sp) # 4-byte Folded Spill
sw s1, 4(sp) # 4-byte Folded Spill
mv s0, a0
li a0, 15
call malloc
mv s1, a0
lui a0, %hi(.L.str)
addi a1, a0, %lo(.L.str)
mv a0, s1
mv a2, s0
call sprintf
mv a0, s1
lw ra, 12(sp) # 4-byte Folded Reload
lw s0, 8(sp) # 4-byte Folded Reload
lw s1, 4(sp) # 4-byte Folded Reload
addi sp, sp, 16
ret
.Lfunc_end8:
.size toString, .Lfunc_end8-toString
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl getString # -- Begin function getString
.p2align 1
.type getString,@function
getString: # @getString
# %bb.0:
addi sp, sp, -48
sw ra, 44(sp) # 4-byte Folded Spill
sw s0, 40(sp) # 4-byte Folded Spill
sw s1, 36(sp) # 4-byte Folded Spill
sw s2, 32(sp) # 4-byte Folded Spill
sw s3, 28(sp) # 4-byte Folded Spill
sw s4, 24(sp) # 4-byte Folded Spill
sw s5, 20(sp) # 4-byte Folded Spill
sw s6, 16(sp) # 4-byte Folded Spill
sw s7, 12(sp) # 4-byte Folded Spill
sw s8, 8(sp) # 4-byte Folded Spill
li a0, 11
call malloc
mv s8, a0
lui a0, %hi(.L.str.4)
addi s2, a0, %lo(.L.str.4)
addi a1, sp, 7
mv a0, s2
call scanf
li s3, 1
bne a0, s3, .LBB9_11
# %bb.1: # %.preheader1
li s1, 0
li s4, 10
li s5, 13
mv s6, s8
li s7, 10
j .LBB9_4
.LBB9_2: # in Loop: Header=BB9_4 Depth=1
mv s8, s6
.LBB9_3: # in Loop: Header=BB9_4 Depth=1
addi s0, s1, 1
add s1, s1, s8
sb a0, 0(s1)
addi a1, sp, 7
mv a0, s2
call scanf
mv s1, s0
bne a0, s3, .LBB9_13
.LBB9_4: # =>This Loop Header: Depth=1
# Child Loop BB9_9 Depth 2
lbu a0, 7(sp)
beq a0, s4, .LBB9_12
# %bb.5: # in Loop: Header=BB9_4 Depth=1
beq a0, s5, .LBB9_12
# %bb.6: # in Loop: Header=BB9_4 Depth=1
bne s1, s7, .LBB9_2
# %bb.7: # in Loop: Header=BB9_4 Depth=1
slli s7, s1, 1
addi a0, s7, 1
call malloc
mv s8, a0
beqz s1, .LBB9_10
# %bb.8: # %.preheader
# in Loop: Header=BB9_4 Depth=1
add a0, s8, s1
mv a1, s6
mv a2, s8
.LBB9_9: # Parent Loop BB9_4 Depth=1
# => This Inner Loop Header: Depth=2
lbu a3, 0(a1)
sb a3, 0(a2)
addi a2, a2, 1
addi a1, a1, 1
bne a2, a0, .LBB9_9
.LBB9_10: # in Loop: Header=BB9_4 Depth=1
mv a0, s6
call free
lbu a0, 7(sp)
mv s6, s8
j .LBB9_3
.LBB9_11:
li s0, 0
j .LBB9_13
.LBB9_12:
mv s0, s1
mv s8, s6
.LBB9_13:
add s0, s0, s8
sb zero, 0(s0)
mv a0, s8
lw ra, 44(sp) # 4-byte Folded Reload
lw s0, 40(sp) # 4-byte Folded Reload
lw s1, 36(sp) # 4-byte Folded Reload
lw s2, 32(sp) # 4-byte Folded Reload
lw s3, 28(sp) # 4-byte Folded Reload
lw s4, 24(sp) # 4-byte Folded Reload
lw s5, 20(sp) # 4-byte Folded Reload
lw s6, 16(sp) # 4-byte Folded Reload
lw s7, 12(sp) # 4-byte Folded Reload
lw s8, 8(sp) # 4-byte Folded Reload
addi sp, sp, 48
ret
.Lfunc_end9:
.size getString, .Lfunc_end9-getString
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl getInt # -- Begin function getInt
.p2align 1
.type getInt,@function
getInt: # @getInt
# %bb.0:
addi sp, sp, -16
sw ra, 12(sp) # 4-byte Folded Spill
lui a0, %hi(.L.str)
addi a0, a0, %lo(.L.str)
addi a1, sp, 8
call scanf
lw a0, 8(sp)
lw ra, 12(sp) # 4-byte Folded Reload
addi sp, sp, 16
ret
.Lfunc_end10:
.size getInt, .Lfunc_end10-getInt
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl .builtin.AllocateClassBody # -- Begin function .builtin.AllocateClassBody
.p2align 1
.type .builtin.AllocateClassBody,@function
.builtin.AllocateClassBody: # @.builtin.AllocateClassBody
# %bb.0:
tail malloc
.Lfunc_end11:
.size .builtin.AllocateClassBody, .Lfunc_end11-.builtin.AllocateClassBody
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl .builtin.GetArrayLength # -- Begin function .builtin.GetArrayLength
.p2align 1
.type .builtin.GetArrayLength,@function
.builtin.GetArrayLength: # @.builtin.GetArrayLength
# %bb.0:
lbu a1, -3(a0)
lbu a2, -4(a0)
lbu a3, -2(a0)
lbu a0, -1(a0)
slli a1, a1, 8
or a1, a1, a2
slli a3, a3, 16
slli a0, a0, 24
or a0, a0, a3
or a0, a0, a1
ret
.Lfunc_end12:
.size .builtin.GetArrayLength, .Lfunc_end12-.builtin.GetArrayLength
# -- End function
.option pop
.option push
.option arch, +a, +c, +m
.globl .builtin.RecursiveAllocateArray # -- Begin function .builtin.RecursiveAllocateArray
.p2align 1
.type .builtin.RecursiveAllocateArray,@function
.builtin.RecursiveAllocateArray: # @.builtin.RecursiveAllocateArray
# %bb.0:
addi sp, sp, -48
sw ra, 44(sp) # 4-byte Folded Spill
sw s0, 40(sp) # 4-byte Folded Spill
sw s1, 36(sp) # 4-byte Folded Spill
sw s2, 32(sp) # 4-byte Folded Spill
sw s3, 28(sp) # 4-byte Folded Spill
sw s4, 24(sp) # 4-byte Folded Spill
sw s5, 20(sp) # 4-byte Folded Spill
sw s6, 16(sp) # 4-byte Folded Spill
sw s7, 12(sp) # 4-byte Folded Spill
lw s0, 0(a2)
mv s3, a1
mv s2, a0
srli s5, s0, 8
srli s4, s0, 16
li a0, 1
srli s6, s0, 24
bne s2, a0, .LBB13_2
# %bb.1:
mul a0, s0, s3
addi a0, a0, 4
call malloc
sb s0, 0(a0)
sb s5, 1(a0)
sb s4, 2(a0)
sb s6, 3(a0)
addi a0, a0, 4
j .LBB13_6
.LBB13_2:
mv s7, a2
slli a0, s0, 2
addi a0, a0, 4
call malloc
sb s0, 0(a0)
sb s5, 1(a0)
sb s4, 2(a0)
sb s6, 3(a0)
addi a0, a0, 4
blez s0, .LBB13_6
# %bb.3:
li s1, 0
addi s2, s2, -1
addi s5, s7, 4
mv s4, a0
mv s0, a0
.LBB13_4: # =>This Inner Loop Header: Depth=1
mv a0, s2
mv a1, s3
mv a2, s5
call .builtin.RecursiveAllocateArray
lw a1, 0(s7)
sw a0, 0(s0)
addi s1, s1, 1
addi s0, s0, 4
blt s1, a1, .LBB13_4
# %bb.5:
mv a0, s4
.LBB13_6:
lw ra, 44(sp) # 4-byte Folded Reload
lw s0, 40(sp) # 4-byte Folded Reload
lw s1, 36(sp) # 4-byte Folded Reload
lw s2, 32(sp) # 4-byte Folded Reload
lw s3, 28(sp) # 4-byte Folded Reload
lw s4, 24(sp) # 4-byte Folded Reload
lw s5, 20(sp) # 4-byte Folded Reload
lw s6, 16(sp) # 4-byte Folded Reload
lw s7, 12(sp) # 4-byte Folded Reload
addi sp, sp, 48
ret
.Lfunc_end13:
.size .builtin.RecursiveAllocateArray, .Lfunc_end13-.builtin.RecursiveAllocateArray
# -- End function
.option pop
.type .L.str,@object # @.str
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "%d"
.size .L.str, 3
.type .L.str.1,@object # @.str.1
.L.str.1:
.asciz "%s"
.size .L.str.1, 3
.type .L.str.2,@object # @.str.2
.L.str.2:
.asciz "%s\n"
.size .L.str.2, 4
.type .L.str.3,@object # @.str.3
.L.str.3:
.asciz "%d\n"
.size .L.str.3, 4
.type .L.str.4,@object # @.str.4
.L.str.4:
.asciz "%c"
.size .L.str.4, 3
.ident "Ubuntu clang version 18.1.8 (++20240731024944+3b5b5c1ec4a3-1~exp1~20240731145000.144)"
.section ".note.GNU-stack","",@progbits

View File

@ -1,6 +1,6 @@
#include <cstddef> #include <cstddef>
#include <functional> #include <functional>
#include "astnode_visitor.h" #include "semantic_visitor.h"
#include "scope.hpp" #include "scope.hpp"
#include "tools.h" #include "tools.h"
@ -444,6 +444,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(AssignExpr_ASTNode *node) {
if (node->dest->expr_type_info != node->src->expr_type_info) { if (node->dest->expr_type_info != node->src->expr_type_info) {
throw SemanticError("Type Mismatch", 1); throw SemanticError("Type Mismatch", 1);
} }
node->expr_type_info = node->src->expr_type_info;
} }
void ASTSemanticCheckVisitor::ActuralVisit(ThisExpr_ASTNode *node) { void ASTSemanticCheckVisitor::ActuralVisit(ThisExpr_ASTNode *node) {

View File

@ -1,6 +1,7 @@
#include <argparse/argparse.hpp> #include <argparse/argparse.hpp>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "IR/IR.h"
#include "semantic/semantic.h" #include "semantic/semantic.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -24,6 +25,7 @@ int main(int argc, char **argv) {
std::shared_ptr<Program_ASTNode> ast; std::shared_ptr<Program_ASTNode> ast;
try { try {
SemanticCheck(fin, ast); SemanticCheck(fin, ast);
auto IR = BuildIR(ast);
} catch (const SemanticError &err) { } catch (const SemanticError &err) {
std::cout << err.what() << std::endl; std::cout << err.what() << std::endl;
return err.GetErrorCode(); return err.GetErrorCode();