#include "instructionssoa.h" #include "storagesoa.h" #include using namespace llvm; InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, StorageSoa *storage) : m_builder(block), m_storage(storage), m_idx(0) { } const char * InstructionsSoa::name(const char *prefix) const { ++m_idx; snprintf(m_name, 32, "%s%d", prefix, m_idx); return m_name; } llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, llvm::Value *z, llvm::Value *w) { VectorType *vectorType = VectorType::get(Type::FloatTy, 4); Constant *constVector = Constant::getNullValue(vectorType); Value *res = m_builder.CreateInsertElement(constVector, x, m_storage->constantInt(0), name("vecx")); res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), name("vecxy")); res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), name("vecxyz")); if (w) res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), name("vecxyzw")); return res; } std::vector InstructionsSoa::arl(const std::vector in) { std::vector res(4); //Extract x's llvm::Value *x1 = m_builder.CreateExtractElement(in[0], m_storage->constantInt(0), name("extractX")); //cast it to an unsigned int x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); res[0] = x1;//vectorFromVals(x1, x2, x3, x4); //only x is valid. the others shouldn't be necessary /* res[1] = Constant::getNullValue(m_floatVecType); res[2] = Constant::getNullValue(m_floatVecType); res[3] = Constant::getNullValue(m_floatVecType); */ return res; } std::vector InstructionsSoa::add(const std::vector in1, const std::vector in2) { std::vector res(4); res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); return res; } std::vector InstructionsSoa::mul(const std::vector in1, const std::vector in2) { std::vector res(4); res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); return res; } void InstructionsSoa::end() { m_builder.CreateRetVoid(); } std::vector InstructionsSoa::madd(const std::vector in1, const std::vector in2, const std::vector in3) { std::vector res = mul(in1, in2); return add(res, in3); } std::vector InstructionsSoa::extractVector(llvm::Value *vector) { std::vector res(4); res[0] = m_builder.CreateExtractElement(vector, m_storage->constantInt(0), name("extract1X")); res[1] = m_builder.CreateExtractElement(vector, m_storage->constantInt(1), name("extract2X")); res[2] = m_builder.CreateExtractElement(vector, m_storage->constantInt(2), name("extract3X")); res[3] = m_builder.CreateExtractElement(vector, m_storage->constantInt(3), name("extract4X")); return res; }