blob: 945c5d4278337efbef925a983d4f0985e8b49959 [file] [log] [blame]
/*
* =====================================================================
* Copyright (c) 2012, PLUMgrid, http://plumgrid.com
*
* This source is subject to the PLUMgrid License.
* All rights reserved.
*
* THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* PLUMgrid confidential information, delete if you are not the
* intended recipient.
*
* =====================================================================
*/
#pragma once
#include <stdio.h>
#include <vector>
#include <string>
#include <set>
#include "cc/node.h"
#include "cc/scope.h"
namespace llvm {
class AllocaInst;
class BasicBlock;
class BranchInst;
class Constant;
class Instruction;
class IRBuilderBase;
class LLVMContext;
class Module;
class StructType;
class SwitchInst;
}
namespace ebpf {
namespace cc {
class BlockStack;
class SwitchStack;
using std::vector;
using std::string;
using std::set;
class CodegenLLVM : public Visitor {
friend class BlockStack;
friend class SwitchStack;
public:
CodegenLLVM(llvm::Module *mod, Scopes *scopes, Scopes *proto_scopes,
bool use_pre_header, const std::string &section);
virtual ~CodegenLLVM();
#define VISIT(type, func) virtual STATUS_RETURN visit_##func(type* n);
EXPAND_NODES(VISIT)
#undef VISIT
virtual STATUS_RETURN visit(Node* n);
int get_table_fd(const std::string &name) const;
private:
STATUS_RETURN emit_short_circuit_and(BinopExprNode* n);
STATUS_RETURN emit_short_circuit_or(BinopExprNode* n);
STATUS_RETURN emit_table_lookup(MethodCallExprNode* n);
STATUS_RETURN emit_table_update(MethodCallExprNode* n);
STATUS_RETURN emit_table_delete(MethodCallExprNode* n);
STATUS_RETURN emit_channel_push(MethodCallExprNode* n);
STATUS_RETURN emit_channel_push_generic(MethodCallExprNode* n);
STATUS_RETURN emit_log(MethodCallExprNode* n);
STATUS_RETURN emit_packet_forward(MethodCallExprNode* n);
STATUS_RETURN emit_packet_replicate(MethodCallExprNode* n);
STATUS_RETURN emit_packet_clone_forward(MethodCallExprNode* n);
STATUS_RETURN emit_packet_forward_self(MethodCallExprNode* n);
STATUS_RETURN emit_packet_drop(MethodCallExprNode* n);
STATUS_RETURN emit_packet_broadcast(MethodCallExprNode* n);
STATUS_RETURN emit_packet_multicast(MethodCallExprNode* n);
STATUS_RETURN emit_packet_push_header(MethodCallExprNode* n);
STATUS_RETURN emit_packet_pop_header(MethodCallExprNode* n);
STATUS_RETURN emit_packet_push_vlan(MethodCallExprNode* n);
STATUS_RETURN emit_packet_pop_vlan(MethodCallExprNode* n);
STATUS_RETURN emit_packet_rewrite_field(MethodCallExprNode* n);
STATUS_RETURN emit_atomic_add(MethodCallExprNode* n);
STATUS_RETURN emit_cksum(MethodCallExprNode* n);
STATUS_RETURN emit_incr_cksum(MethodCallExprNode* n, size_t sz = 0);
STATUS_RETURN emit_lb_hash(MethodCallExprNode* n);
STATUS_RETURN emit_sizeof(MethodCallExprNode* n);
STATUS_RETURN emit_get_usec_time(MethodCallExprNode* n);
STATUS_RETURN emit_forward_to_vnf(MethodCallExprNode* n);
STATUS_RETURN emit_forward_to_group(MethodCallExprNode* n);
STATUS_RETURN print_parser();
STATUS_RETURN print_timer();
STATUS_RETURN print_header();
void indent();
llvm::LLVMContext & ctx() const;
llvm::Constant * const_int(uint64_t val, unsigned bits = 64, bool is_signed = false);
llvm::Value * pop_expr();
llvm::BasicBlock * resolve_label(const string &label);
StatusTuple lookup_var(Node *n, const std::string &name, Scopes::VarScope *scope,
VariableDeclStmtNode **decl, llvm::Value **mem) const;
template <typename... Args> void emitln(const char *fmt, Args&&... params);
template <typename... Args> void lnemit(const char *fmt, Args&&... params);
template <typename... Args> void emit(const char *fmt, Args&&... params);
void emitln(const char *s);
void lnemit(const char *s);
void emit(const char *s);
void emit_comment(Node* n);
FILE* out_;
llvm::Module* mod_;
llvm::IRBuilderBase *b_;
int indent_;
int tmp_reg_index_;
Scopes *scopes_;
Scopes *proto_scopes_;
bool use_pre_header_;
std::string section_;
vector<vector<string> > free_instructions_;
vector<string> table_inits_;
map<string, string> proto_rewrites_;
map<TableDeclStmtNode *, llvm::GlobalVariable *> tables_;
map<TableDeclStmtNode *, int> table_fds_;
map<VariableDeclStmtNode *, llvm::Value *> vars_;
map<StructDeclStmtNode *, llvm::StructType *> structs_;
map<string, llvm::BasicBlock *> labels_;
llvm::BasicBlock *entry_bb_;
llvm::SwitchInst *cur_switch_;
llvm::Value *expr_;
llvm::AllocaInst *retval_;
};
} // namespace cc
} // namespace ebpf