add getelementptr/load/call

dev
MITSUNARI Shigeo 9 years ago
parent 4d03fa5dc5
commit ab390ce3ec
  1. 39
      src/gen.cpp
  2. 132
      src/llvm_gen.hpp
  3. 2
      src/once.txt

@ -2,13 +2,17 @@
struct OnceCode : public mcl::Generator {
uint32_t unit2;
Function gen_mulUU()
Function mulUU;
Function extractHigh;
Function mulPos;
void gen_mulUU()
{
resetGlobalIdx();
Operand z(Int, unit2);
Operand x(Int, unit);
Operand y(Int, unit);
Function mulUU("mulUU", z, x, y);
mulUU = Function("mulUU", z, x, y);
beginFunc(mulUU);
x = zext(x, unit2);
@ -16,14 +20,13 @@ struct OnceCode : public mcl::Generator {
z= mul(x, y);
ret(z);
endFunc();
return mulUU;
}
Function gen_extractHigh()
void gen_extractHigh()
{
resetGlobalIdx();
Operand z(Int, unit);
Operand x(Int, unit2);
Function extractHigh("extractHigh", z, x);
extractHigh = Function("extractHigh", z, x);
extractHigh.setPrivate();
beginFunc(extractHigh);
@ -31,25 +34,31 @@ struct OnceCode : public mcl::Generator {
z = trunc(x, unit);
ret(z);
endFunc();
return extractHigh;
}
Function gen_mulPv(int bu)
void gen_mulPos()
{
Operand z(Int, bu);
Operand px(Pointer, unit);
resetGlobalIdx();
Operand xy(Int, unit2);
Operand px(IntPtr, unit);
Operand y(Int, unit);
Function mulPv("mulPv", z, px, y);
beginFunc(mulPv);
Operand i(Int, unit);
mulPos = Function("mulPos", xy, px, y, i);
mulPos.setPrivate();
beginFunc(mulPos);
px = getelementptr(px, i);
Operand x = load(px);
xy = call(mulUU, x, y);
ret(xy);
endFunc();
return mulPv;
}
void gen(uint32_t unit, uint32_t bit)
{
set(unit, bit);
unit2 = unit * 2;
Function mulUU = gen_mulUU();
Function extractHigh = gen_extractHigh();
// Function mulPv = gen_mulPv(bu);
gen_mulUU();
gen_extractHigh();
gen_mulPos();
}
};

@ -11,6 +11,10 @@
#include <cybozu/exception.hpp>
#include <cybozu/itoa.hpp>
#include <stdio.h>
#ifdef _MSC_VER
// #pragma warning(push)
#pragma warning(disable : 4458)
#endif
namespace mcl {
@ -49,6 +53,25 @@ File Param<dummy>::f;
} // mcl::impl
struct Generator {
static const uint8_t Void = 0;
static const uint8_t Int = 1;
static const uint8_t Imm = 2;
static const uint8_t Ptr = 1 << 7;
static const uint8_t IntPtr = Int | Ptr;
struct Type {
uint8_t type;
bool isPtr;
Type(int type = 0)
: type(static_cast<uint8_t>(type & ~Ptr))
, isPtr((type & Ptr) != 0)
{
}
static inline friend std::ostream& operator<<(std::ostream& os, const Type& self)
{
return os << (self.type | (self.isPtr ? Ptr : 0));
}
};
Type type;
uint32_t unit;
uint32_t bit;
uint32_t N;
@ -63,12 +86,6 @@ struct Generator {
{
impl::Param<>::f.open(file);
}
enum Type {
Void = 0,
Int = 1,
Pointer = 2,
Imm = 3
};
struct Operand;
struct Function;
struct Eval;
@ -100,6 +117,12 @@ struct Generator {
void ret(const Operand& r);
Eval lshr(const Operand& x, uint32_t size);
Eval trunc(const Operand& x, uint32_t size);
Eval getelementptr(const Operand& p, const Operand& i);
Eval load(const Operand& p);
Eval call(const Function& f, const Operand& op1);
Eval call(const Function& f, const Operand& op1, const Operand& op2);
Eval call(const Function& f, const Operand& op1, const Operand& op2, const Operand& op3);
Eval call(const Function& f, const Operand& op1, const Operand& op2, const Operand& op3, const Operand& op4);
};
struct Generator::Operand {
@ -129,11 +152,13 @@ struct Generator::Operand {
void update() { idx++; }
std::string toStr() const
{
switch (type) {
if (type.isPtr) {
return getType() + " " + getName();
}
switch (type.type) {
default:
return "void";
case Int:
case Pointer:
return getType() + " " + getName();
case Imm:
return cybozu::itoa(imm);
@ -141,22 +166,25 @@ struct Generator::Operand {
}
std::string getType() const
{
switch (type) {
std::string s;
switch (type.type) {
default:
return "";
case Int:
return std::string("i") + cybozu::itoa(bit);
case Pointer:
return std::string("i") + cybozu::itoa(bit) + "*";
s = std::string("i") + cybozu::itoa(bit);
break;
}
if (type.isPtr) {
s += "*";
}
return s;
}
std::string getName() const
{
switch (type) {
switch (type.type) {
default:
return "";
case Int:
case Pointer:
std::string str("%");
str += name;
if (idx > 0) str += "_" + cybozu::itoa(idx);
@ -272,6 +300,12 @@ inline Generator::Eval Generator::mul(const Generator::Operand& x, const Generat
return e;
}
inline void Generator::ret(const Generator::Operand& x)
{
std::string s = "ret " + x.toStr();
put(s);
}
inline Generator::Eval Generator::lshr(const Generator::Operand& x, uint32_t size)
{
Eval e;
@ -291,12 +325,76 @@ inline Generator::Eval Generator::trunc(const Generator::Operand& x, uint32_t si
return e;
}
inline void Generator::ret(const Generator::Operand& x)
inline Generator::Eval Generator::getelementptr(const Generator::Operand& p, const Generator::Operand& i)
{
std::string s = "ret " + x.toStr();
put(s);
Eval e;
e.op = p;
e.s = "getelementptr ";
e.s += p.toStr() + ", " + i.toStr();
return e;
}
inline Generator::Eval Generator::load(const Generator::Operand& p)
{
if (!p.type.isPtr) throw cybozu::Exception("Generator:load:not pointer") << p.type;
Eval e;
e.op = p;
e.op.type.isPtr = false;
e.s = "load ";
e.s += p.toStr();
return e;
}
namespace impl {
static inline Generator::Eval callSub(const Generator::Function& f, const Generator::Operand **opTbl, size_t opNum)
{
if (f.opv.size() != opNum) throw cybozu::Exception("implcallSub:bad num of arg") << f.opv.size() << opNum;
Generator::Eval e;
e.op = f.ret;
e.s = "call ";
e.s += f.ret.getType();
e.s += " @" + f.name + "(";
for (size_t i = 0; i < opNum; i++) {
if (i > 0) {
e.s += ", ";
}
e.s += opTbl[i]->toStr();
}
e.s += ")";
return e;
}
}
inline Generator::Eval Generator::call(const Generator::Function& f, const Generator::Operand& op1)
{
const Operand *tbl[] = { &op1 };
return impl::callSub(f, tbl, CYBOZU_NUM_OF_ARRAY(tbl));
}
inline Generator::Eval Generator::call(const Generator::Function& f, const Generator::Operand& op1, const Generator::Operand& op2)
{
const Operand *tbl[] = { &op1, &op2 };
return impl::callSub(f, tbl, CYBOZU_NUM_OF_ARRAY(tbl));
}
inline Generator::Eval Generator::call(const Generator::Function& f, const Generator::Operand& op1, const Generator::Operand& op2, const Generator::Operand& op3)
{
const Operand *tbl[] = { &op1, &op2, &op3 };
return impl::callSub(f, tbl, CYBOZU_NUM_OF_ARRAY(tbl));
}
inline Generator::Eval Generator::call(const Generator::Function& f, const Generator::Operand& op1, const Generator::Operand& op2, const Generator::Operand& op3, const Generator::Operand& op4)
{
const Operand *tbl[] = { &op1, &op2, &op3, &op4 };
return impl::callSub(f, tbl, CYBOZU_NUM_OF_ARRAY(tbl));
}
#define MCL_GEN_FUNCTION(name, ...) Function name(#name, __VA_ARGS__)
} // mcl
#ifdef _MSC_VER
// #pragma warning(pop)
#endif

@ -13,7 +13,7 @@ define private i$(unit) @extractHigh$(unit)(i$(u2) %x)
%t1 = trunc i$(unit*2) %t0 to i$(unit)
ret i$(unit) %t1
}
define i$(u2) @mulPos$(unit)x$(unit)(i$(unit) *%px, i$(unit) %y, i$(unit) %i)
define private i$(u2) @mulPos$(unit)x$(unit)(i$(unit) *%px, i$(unit) %y, i$(unit) %i)
{
%p = getelementptr i$(unit)* %px, i$(unit) %i
%x = load i$(unit)* %p

Loading…
Cancel
Save