summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2008-02-14 22:42:57 -0500
committerZack Rusin <[email protected]>2008-02-15 01:17:17 -0500
commitf70cc89dbc8c0f3e58d6cf8eca92e2df1677c86e (patch)
tree66bed76e9f8e5929220b6af54df0e7bba0051ab8
parentae3375987fe9968f822442a0ce49b97f5f0a4070 (diff)
redo the way immediates are handled
implement madd start implementing arl
-rw-r--r--src/mesa/pipe/llvm/instructionssoa.cpp64
-rw-r--r--src/mesa/pipe/llvm/instructionssoa.h9
-rw-r--r--src/mesa/pipe/llvm/storagesoa.cpp142
-rw-r--r--src/mesa/pipe/llvm/storagesoa.h15
-rw-r--r--src/mesa/pipe/llvm/tgsitollvm.cpp17
5 files changed, 190 insertions, 57 deletions
diff --git a/src/mesa/pipe/llvm/instructionssoa.cpp b/src/mesa/pipe/llvm/instructionssoa.cpp
index 0c2032e56ff..1e144393e0f 100644
--- a/src/mesa/pipe/llvm/instructionssoa.cpp
+++ b/src/mesa/pipe/llvm/instructionssoa.cpp
@@ -1,12 +1,67 @@
#include "instructionssoa.h"
+#include "storagesoa.h"
+
+#include <llvm/Constants.h>
+
+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<llvm::Value*> InstructionsSoa::arl(const std::vector<llvm::Value*> in)
+{
+ std::vector<llvm::Value*> res(4);
+
+ //Extract the first x (all 4 should be the same)
+ llvm::Value *x = m_builder.CreateExtractElement(in[0],
+ m_storage->constantInt(0),
+ name("extractX"));
+ //cast it to an unsigned int
+ x = m_builder.CreateFPToUI(x, IntegerType::get(32), name("xIntCast"));
+
+ res[0] = x;
+ //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<llvm::Value*> InstructionsSoa::add(const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2)
{
@@ -38,9 +93,10 @@ void InstructionsSoa::end()
m_builder.CreateRetVoid();
}
-const char * InstructionsSoa::name(const char *prefix) const
+std::vector<llvm::Value*> InstructionsSoa::madd(const std::vector<llvm::Value*> in1,
+ const std::vector<llvm::Value*> in2,
+ const std::vector<llvm::Value*> in3)
{
- ++m_idx;
- snprintf(m_name, 32, "%s%d", prefix, m_idx);
- return m_name;
+ std::vector<llvm::Value*> res = mul(in1, in2);
+ return add(res, in3);
}
diff --git a/src/mesa/pipe/llvm/instructionssoa.h b/src/mesa/pipe/llvm/instructionssoa.h
index 01955015844..25ff4ac712a 100644
--- a/src/mesa/pipe/llvm/instructionssoa.h
+++ b/src/mesa/pipe/llvm/instructionssoa.h
@@ -46,17 +46,24 @@ public:
InstructionsSoa(llvm::Module *mod, llvm::Function *func,
llvm::BasicBlock *block, StorageSoa *storage);
+ std::vector<llvm::Value*> arl(const std::vector<llvm::Value*> in);
+
std::vector<llvm::Value*> add(const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2);
+ std::vector<llvm::Value*> madd(const std::vector<llvm::Value*> in1,
+ const std::vector<llvm::Value*> in2,
+ const std::vector<llvm::Value*> in3);
std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2);
void end();
private:
const char * name(const char *prefix) const;
+ llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y,
+ llvm::Value *z, llvm::Value *w);
private:
llvm::LLVMFoldingBuilder m_builder;
-
+ StorageSoa *m_storage;
private:
mutable int m_idx;
mutable char m_name[32];
diff --git a/src/mesa/pipe/llvm/storagesoa.cpp b/src/mesa/pipe/llvm/storagesoa.cpp
index 408b29417ce..f8f4193fd7f 100644
--- a/src/mesa/pipe/llvm/storagesoa.cpp
+++ b/src/mesa/pipe/llvm/storagesoa.cpp
@@ -55,39 +55,81 @@ StorageSoa::StorageSoa(llvm::BasicBlock *block,
m_output(output),
m_consts(consts),
m_temps(temps),
+ m_immediates(0),
m_idx(0)
{
}
void StorageSoa::addImmediate(float *vec)
{
- float vals[4]; //decompose into soa
-
- vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0];
- llvm::Value *xChannel = createConstGlobalVector(vals);
-
- vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1];
- llvm::Value *yChannel = createConstGlobalVector(vals);
+ std::vector<float> vals(4);
+ vals[0] = vec[0];
+ vals[1] = vec[1];
+ vals[2] = vec[2];
+ vals[3] = vec[3];
+ m_immediatesToFlush.push_back(vals);
+}
+void StorageSoa::declareImmediates()
+{
+ if (m_immediatesToFlush.empty())
+ return;
- vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2];
- llvm::Value *zChannel = createConstGlobalVector(vals);
+ VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
+ ArrayType *vectorChannels = ArrayType::get(vectorType, 4);
+ ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size());
- vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3];
- llvm::Value *wChannel = createConstGlobalVector(vals);
+ m_immediates = new GlobalVariable(
+ /*Type=*/arrayType,
+ /*isConstant=*/false,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Initializer=*/0, // has initializer, specified below
+ /*Name=*/name("immediates"),
+ currentModule());
- std::vector<llvm::Value*> res(4);
- res[0] = xChannel;
- res[1] = yChannel;
- res[2] = zChannel;
- res[3] = wChannel;
+ std::vector<Constant*> arrayVals;
+ for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) {
+ std::vector<float> vec = m_immediatesToFlush[i];
+ std::vector<float> vals(4);
+ std::vector<Constant*> channelArray;
+
+ vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0];
+ llvm::Constant *xChannel = createConstGlobalVector(vals);
+
+ vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1];
+ llvm::Constant *yChannel = createConstGlobalVector(vals);
+
+ vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2];
+ llvm::Constant *zChannel = createConstGlobalVector(vals);
+
+ vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3];
+ llvm::Constant *wChannel = createConstGlobalVector(vals);
+ channelArray.push_back(xChannel);
+ channelArray.push_back(yChannel);
+ channelArray.push_back(zChannel);
+ channelArray.push_back(wChannel);
+ Constant *constChannels = ConstantArray::get(vectorChannels,
+ channelArray);
+ arrayVals.push_back(constChannels);
+ }
+ Constant *constArray = ConstantArray::get(arrayType, arrayVals);
+ m_immediates->setInitializer(constArray);
- m_immediates[m_immediates.size()] = res;
+ m_immediatesToFlush.clear();
}
llvm::Value *StorageSoa::addrElement(int idx) const
{
- return 0;
+ std::map<int, llvm::Value*>::const_iterator itr = m_addresses.find(idx);
+ if (itr == m_addresses.end()) {
+ debug_printf("Trying to access invalid shader 'address'\n");
+ return 0;
+ }
+ llvm::Value * res = (*itr).second;
+
+ res = new LoadInst(res, name("addr"), false, m_block);
+
+ return res;
}
std::vector<llvm::Value*> StorageSoa::inputElement(int idx, llvm::Value *indIdx)
@@ -145,25 +187,21 @@ std::vector<llvm::Value*> StorageSoa::tempElement(int idx, llvm::Value *indIdx)
std::vector<llvm::Value*> StorageSoa::immediateElement(int idx)
{
std::vector<llvm::Value*> res(4);
- res = m_immediates[idx];
- res[0] = new LoadInst(res[0], name("immx"), false, m_block);
- res[1] = new LoadInst(res[1], name("immy"), false, m_block);
- res[2] = new LoadInst(res[2], name("immz"), false, m_block);
- res[3] = new LoadInst(res[3], name("immw"), false, m_block);
+ res[0] = element(m_immediates, idx, 0);
+ res[1] = element(m_immediates, idx, 1);
+ res[2] = element(m_immediates, idx, 2);
+ res[3] = element(m_immediates, idx, 3);
return res;
}
-llvm::Value * StorageSoa::extractIndex(llvm::Value *vec)
-{
- return 0;
-}
-
llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, int index,
int channel) const
{
std::vector<Value*> indices;
+ if (m_immediates == ptr)
+ indices.push_back(constantInt(0));
indices.push_back(constantInt(index));
indices.push_back(constantInt(channel));
@@ -220,17 +258,9 @@ llvm::Module * StorageSoa::currentModule() const
return m_block->getParent()->getParent();
}
-llvm::Value * StorageSoa::createConstGlobalVector(float *vec)
+llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector<float> &vec)
{
VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
- GlobalVariable *immediate = new GlobalVariable(
- /*Type=*/vectorType,
- /*isConstant=*/true,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Initializer=*/0, // has initializer, specified below
- /*Name=*/name("immediate"),
- currentModule());
-
std::vector<Constant*> immValues;
ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0]));
ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1]));
@@ -242,16 +272,15 @@ llvm::Value * StorageSoa::createConstGlobalVector(float *vec)
immValues.push_back(constw);
Constant *constVector = ConstantVector::get(vectorType, immValues);
- // Global Variable Definitions
- immediate->setInitializer(constVector);
-
- return immediate;
+ return constVector;
}
std::vector<llvm::Value*> StorageSoa::load(Argument type, int idx, int swizzle,
- llvm::Value *indIdx )
+ llvm::Value *indIdx)
{
std::vector<llvm::Value*> val(4);
+ debug_printf("XXXXXXXXX indIdx = %p\n", indIdx);
+ assert(!indIdx);
switch(type) {
case Input:
val = inputElement(idx, indIdx);
@@ -269,7 +298,7 @@ std::vector<llvm::Value*> StorageSoa::load(Argument type, int idx, int swizzle,
val = immediateElement(idx);
break;
case Address:
- debug_printf("Address not handled in the fetch phase!\n");
+ debug_printf("Address not handled in the load phase!\n");
assert(0);
break;
}
@@ -299,6 +328,17 @@ void StorageSoa::store(Argument type, int idx, const std::vector<llvm::Value*> &
case Input:
out = m_input;
break;
+ case Address: {
+ llvm::Value *addr = m_addresses[idx];
+ if (!addr) {
+ addAddress(idx);
+ addr = m_addresses[idx];
+ assert(addr);
+ }
+ new StoreInst(val[0], addr, false, m_block);
+ return;
+ break;
+ }
default:
debug_printf("Can't save output of this type: %d !\n", type);
assert(0);
@@ -322,3 +362,19 @@ void StorageSoa::store(Argument type, int idx, const std::vector<llvm::Value*> &
new StoreInst(val[3], wChannel, false, m_block);
}
}
+
+void StorageSoa::addAddress(int idx)
+{
+ GlobalVariable *val = new GlobalVariable(
+ /*Type=*/IntegerType::get(32),
+ /*isConstant=*/false,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Initializer=*/0, // has initializer, specified below
+ /*Name=*/name("address"),
+ currentModule());
+ //val->setInitializer(Constant::getNullValue(IntegerType::get(32)));
+ val->setInitializer(constantInt(1));
+
+ debug_printf("adding to %d\n", idx);
+ m_addresses[idx] = val;
+}
diff --git a/src/mesa/pipe/llvm/storagesoa.h b/src/mesa/pipe/llvm/storagesoa.h
index d59168f07da..ea5db2b4276 100644
--- a/src/mesa/pipe/llvm/storagesoa.h
+++ b/src/mesa/pipe/llvm/storagesoa.h
@@ -29,12 +29,14 @@
#define STORAGESOA_H
#include <vector>
+#include <list>
#include <map>
namespace llvm {
class BasicBlock;
class Constant;
class ConstantInt;
+ class GlobalVariable;
class LoadInst;
class Value;
class VectorType;
@@ -66,20 +68,22 @@ public:
int mask);
void addImmediate(float *vec);
+ void declareImmediates();
+
+ void addAddress(int idx);
llvm::Value * addrElement(int idx) const;
- llvm::Value *extractIndex(llvm::Value *vec);
+ llvm::ConstantInt *constantInt(int) const;
private:
llvm::Value *elementPointer(llvm::Value *ptr, int index,
int channel) const;
llvm::Value *element(llvm::Value *ptr, int index,
int channel) const;
const char *name(const char *prefix) const;
- llvm::ConstantInt *constantInt(int) const;
llvm::Value *alignedArrayLoad(llvm::Value *val);
llvm::Module *currentModule() const;
- llvm::Value *createConstGlobalVector(float *vec);
+ llvm::Constant *createConstGlobalVector(const std::vector<float> &vec);
std::vector<llvm::Value*> inputElement(int idx, llvm::Value *indIdx =0);
std::vector<llvm::Value*> constElement(int idx, llvm::Value *indIdx =0);
@@ -93,8 +97,11 @@ private:
llvm::Value *m_output;
llvm::Value *m_consts;
llvm::Value *m_temps;
+ llvm::GlobalVariable *m_immediates;
+
+ std::map<int, llvm::Value*> m_addresses;
- std::map<int, std::vector<llvm::Value*> > m_immediates;
+ std::vector<std::vector<float> > m_immediatesToFlush;
mutable std::map<int, llvm::ConstantInt*> m_constInts;
mutable char m_name[32];
diff --git a/src/mesa/pipe/llvm/tgsitollvm.cpp b/src/mesa/pipe/llvm/tgsitollvm.cpp
index 0c2c3a9a0ac..071b7d112e4 100644
--- a/src/mesa/pipe/llvm/tgsitollvm.cpp
+++ b/src/mesa/pipe/llvm/tgsitollvm.cpp
@@ -148,10 +148,14 @@ translate_declaration(struct gallivm_ir *prog,
static void
translate_declarationir(struct gallivm_ir *,
llvm::Module *,
- StorageSoa *,
- struct tgsi_full_declaration *,
+ StorageSoa *storage,
+ struct tgsi_full_declaration *decl,
struct tgsi_full_declaration *)
{
+ if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
+ int idx = decl->u.DeclarationRange.First;
+ storage->addAddress(idx);
+ }
}
static void
@@ -703,7 +707,7 @@ translate_instructionir(llvm::Module *module,
if (src->SrcRegister.Indirect) {
indIdx = storage->addrElement(src->SrcRegisterInd.Index);
- indIdx = storage->extractIndex(indIdx);
+ debug_printf("AAAAAAAAAAAAAAA INDIRECT %p\n", indIdx);
}
if (src->SrcRegister.File == TGSI_FILE_CONSTANT) {
val = storage->load(StorageSoa::Const,
@@ -713,13 +717,13 @@ translate_instructionir(llvm::Module *module,
src->SrcRegister.Index, swizzle, indIdx);
} else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
val = storage->load(StorageSoa::Temp,
- src->SrcRegister.Index, swizzle);
+ src->SrcRegister.Index, swizzle, indIdx);
} else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) {
val = storage->load(StorageSoa::Output,
src->SrcRegister.Index, swizzle, indIdx);
} else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
val = storage->load(StorageSoa::Immediate,
- src->SrcRegister.Index, swizzle);
+ src->SrcRegister.Index, swizzle, indIdx);
} else {
fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
return;
@@ -731,6 +735,7 @@ translate_instructionir(llvm::Module *module,
std::vector<llvm::Value*> out(4);
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL: {
+ out = instr->arl(inputs[0]);
}
break;
case TGSI_OPCODE_MOV: {
@@ -780,6 +785,7 @@ translate_instructionir(llvm::Module *module,
}
break;
case TGSI_OPCODE_MAD: {
+ out = instr->madd(inputs[0], inputs[1], inputs[2]);
}
break;
case TGSI_OPCODE_SUB: {
@@ -1198,6 +1204,7 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir,
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
+ storage.declareImmediates();
translate_instructionir(mod, &storage, &instr,
&parse.FullToken.FullInstruction,
&fi, instno);