#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)
{
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);
}
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)
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));
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]));
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);
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;
}
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);
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;
+}
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
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,
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;
std::vector<llvm::Value*> out(4);
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL: {
+ out = instr->arl(inputs[0]);
}
break;
case TGSI_OPCODE_MOV: {
}
break;
case TGSI_OPCODE_MAD: {
+ out = instr->madd(inputs[0], inputs[1], inputs[2]);
}
break;
case TGSI_OPCODE_SUB: {
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
+ storage.declareImmediates();
translate_instructionir(mod, &storage, &instr,
&parse.FullToken.FullInstruction,
&fi, instno);