const std::string UlamType::getTmpStorageTypeAsString(s32 sizebyints) { std::string ctype; switch(sizebyints) { case 0: //e.g. empty quarks case 32: ctype = "u32"; break; case 64: ctype = "u64"; break; case 96: ctype = "BV96"; break; default: { assert(!isScalar()); //ctype = getTmpStorageTypeAsString(getItemWordSize()); //u32, u64 (inf loop) std::ostringstream cstr; if(sizebyints == (s32) getItemWordSize()) cstr << "BitVector<" << getBitSize() << ">"; else cstr << "BitVector<" << getTotalBitSize() << ">"; //entire array ctype = cstr.str(); } }; return ctype; } //getTmpStorageTypeAsString
void UlamTypePrimitive::genUlamTypeWriteDefinitionForC(File * fp) { u32 totbitsize = getTotalBitSize(); if(totbitsize <= BITSPERATOM) //Big 96bit array is unpacked, but.. (t3969) { m_state.indent(fp); fp->write("void write"); fp->write("(const "); fp->write(getTmpStorageTypeAsString().c_str()); //s32 or u32, s64 or u64 fp->write("& v) { BVS::"); fp->write(writeMethodForCodeGen().c_str()); fp->write("(0u, "); fp->write_decimal_unsigned(totbitsize); //incl WriteBig if(isScalar()) { fp->write("u, v); }"); GCNL; } else { fp->write("u, v); } //writes entire array"); GCNL; } } else { //UNPACKED m_state.indent(fp); fp->write("void "); fp->write(" write(const "); fp->write(getTmpStorageTypeAsString().c_str()); //BV fp->write("& bv) { BVS::"); fp->write("WriteBV(0u, bv); "); fp->write("} //writes entire BV"); GCNL; } } //genUlamTypeWriteDefinitionForC
PACKFIT UlamType::getPackable() { PACKFIT rtn = UNPACKED; //was false == 0 u32 len = getTotalBitSize(); //could be 0, e.g. 'unknown' //scalars are considered packable (arraysize == NONARRAYSIZE); Atoms and Ptrs are NOT. if(len <= MAXBITSPERLONG) rtn = PACKEDLOADABLE; else if(len <= MAXSTATEBITS) rtn = PACKED; return rtn; } //getPackable
UlamTypePrimitiveUnary::UlamTypePrimitiveUnary(const UlamKeyTypeSignature key, CompilerState & state) : UlamTypePrimitive(key, state) { s32 bitsize = getBitSize(); if(bitsize <= 0) { m_max = m_min = 0; } else if(bitsize <= MAXBITSPERINT) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = _GetNOnes32((u32) bitsize); m_min = 0; } else if(bitsize <= MAXBITSPERLONG) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = _GetNOnes64((u64) bitsize); m_min = 0; } else m_state.abortGreaterThanMaxBitsPerLong(); }
UlamTypeInt::UlamTypeInt(const UlamKeyTypeSignature key, CompilerState & state) : UlamType(key, state) { s32 bitsize = getBitSize(); if(bitsize <= 0) { m_max = m_min = 0; } else if(bitsize <= MAXBITSPERINT) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = calcBitsizeSignedMax(bitsize); m_min = calcBitsizeSignedMin(bitsize); } else if(bitsize <= MAXBITSPERLONG) { m_wordLengthTotal = calcWordSizeLong(getTotalBitSize()); m_wordLengthItem = calcWordSizeLong(bitsize); m_max = calcBitsizeSignedMaxLong(bitsize); m_min = calcBitsizeSignedMinLong(bitsize); } else assert(0); }
UlamTypePrimitiveInt::UlamTypePrimitiveInt(const UlamKeyTypeSignature key, CompilerState & state) : UlamTypePrimitive(key, state) { s32 bitsize = getBitSize(); if(bitsize <= 0) { m_max = m_min = 0; } else if(bitsize <= MAXBITSPERINT) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = calcBitsizeSignedMax(bitsize); m_min = calcBitsizeSignedMin(bitsize); } else if(bitsize <= MAXBITSPERLONG) { m_wordLengthTotal = calcWordSize(getTotalBitSize()); m_wordLengthItem = calcWordSize(bitsize); m_max = calcBitsizeSignedMaxLong(bitsize); m_min = calcBitsizeSignedMinLong(bitsize); } else m_state.abortGreaterThanMaxBitsPerLong(); }
void UlamTypePrimitive::genUlamTypeReadDefinitionForC(File * fp) { u32 totbitsize = getTotalBitSize(); if(totbitsize <= BITSPERATOM) //Big 96bit array is unpacked, but.. (t3969) { m_state.indent(fp); fp->write("const "); fp->write(getTmpStorageTypeAsString().c_str()); //u32 or u64 fp->write(" read"); fp->write("() const { return BVS::"); fp->write(readMethodForCodeGen().c_str()); fp->write("(0u, "); fp->write_decimal_unsigned(totbitsize); //incl ReadBig if(isScalar()) { fp->write("u); }"); GCNL; //done } else { fp->write("u); } //reads entire array"); GCNL; } } else { //UNPACKED (e.g. t3975) m_state.indent(fp); fp->write("const "); fp->write(getTmpStorageTypeAsString().c_str()); //BV fp->write(" read"); fp->write("() const { "); fp->write(getTmpStorageTypeAsString().c_str()); //BV fp->write(" rtnunpbv; this->BVS::"); fp->write("ReadBV(0u, rtnunpbv); return rtnunpbv; "); fp->write("} //reads entire BV"); GCNL; } } //genUlamTypeReadDefinitionForC
u32 UlamType::getSizeofUlamType() { return getTotalBitSize(); //by default }
void UlamTypePrimitive::genUlamTypeMangledImmediateModelParameterDefinitionForC(File * fp) { assert(isScalar()); //since arrays cannot be initialized const std::string mangledName = getImmediateModelParameterStorageTypeAsString(); std::ostringstream ud; ud << "Ud_" << mangledName; //d for define (p used for atomicparametrictype) std::string udstr = ud.str(); m_state.m_currentIndentLevel = 0; m_state.indent(fp); fp->write("#ifndef "); fp->write(udstr.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("#define "); fp->write(udstr.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("namespace MFM{\n"); fp->write("\n"); m_state.m_currentIndentLevel++; m_state.indent(fp); fp->write("template<class EC>\n"); m_state.indent(fp); fp->write("struct "); fp->write(mangledName.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("{\n"); m_state.m_currentIndentLevel++; m_state.indent(fp); fp->write("// immediate model parameter definition:\n"); //typedef atomic parameter type inside struct UlamType::genStandardConfigTypedefTypenames(fp, m_state); s32 len = getTotalBitSize(); //reference to storage in atom m_state.indent(fp); fp->write("T* m_stgPtr; //ptr to storage here!"); GCNL; // default constructor m_state.indent(fp); fp->write(mangledName.c_str()); fp->write("() : m_stgPtr(NULL) { }"); GCNL; m_state.indent(fp); fp->write("void init(T& realStg) { m_stgPtr = &realStg; }"); GCNL; //read method: MFM model parameters are right justified in the atom // NO write method for MPs in ulam. t3259 m_state.indent(fp); fp->write("const "); fp->write(getTmpStorageTypeAsString().c_str()); //s32 or u32, s64 or u64 fp->write(" read(const UlamContext<EC>& uc) const { MFM_API_ASSERT_NONNULL(m_stgPtr); AtomRefBitStorage<EC> mpfoo(*m_stgPtr); return UlamRef<EC>(BPA - "); fp->write_decimal(len); //by convention at the end of the atom fp->write("u, "); fp->write_decimal(len); fp->write("u, mpfoo, NULL, UlamRef<EC>::PRIMITIVE, uc)."); //origin 0u fp->write(readMethodForCodeGen().c_str()); fp->write("(); }"); GCNL; m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("};\n"); m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("} //MFM\n"); m_state.indent(fp); fp->write("#endif /*"); fp->write(udstr.c_str()); fp->write(" */\n\n"); } //genUlamTypeMangledImmediateModelParameterDefinitionForC
//generates immediates with local storage void UlamTypePrimitive::genUlamTypeMangledDefinitionForC(File * fp) { u32 len = getTotalBitSize(); //could be 0, includes arrays m_state.m_currentIndentLevel = 0; UTI anyuti = Nav; AssertBool anyDefined = m_state.anyDefinedUTI(m_key, anyuti); assert(anyDefined); UTI scalaruti = m_state.getUlamTypeAsScalar(anyuti); UlamType * scalarut = m_state.getUlamTypeByIndex(scalaruti); const std::string scalarmangledName = scalarut->getUlamTypeMangledName(); const std::string mangledName = getUlamTypeImmediateMangledName(); const std::string automangledName = getUlamTypeImmediateAutoMangledName(); std::ostringstream ud; ud << "Ud_" << mangledName; //d for define (p used for atomicparametrictype) std::string udstr = ud.str(); m_state.indent(fp); fp->write("#ifndef "); fp->write(udstr.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("#define "); fp->write(udstr.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("namespace MFM{\n"); fp->write("\n"); m_state.m_currentIndentLevel++; m_state.indent(fp); fp->write("template<class EC>\n"); m_state.indent(fp); fp->write("struct "); fp->write(mangledName.c_str()); fp->write(" : public "); fp->write("BitVectorBitStorage"); fp->write("<EC, BitVector<"); fp->write_decimal_unsigned(len); fp->write("u> >\n"); m_state.indent(fp); fp->write("{\n"); m_state.m_currentIndentLevel++; //typedef atomic parameter type inside struct UlamType::genStandardConfigTypedefTypenames(fp, m_state); m_state.indent(fp); fp->write("typedef BitVector<"); fp->write_decimal_unsigned(len); fp->write("> BV;"); GCNL; m_state.indent(fp); fp->write("typedef BitVectorBitStorage<EC, BV> BVS;"); GCNL; fp->write("\n"); //put read/write methods before constructrtors that may use them. //read BV method genUlamTypeReadDefinitionForC(fp); //write BV method genUlamTypeWriteDefinitionForC(fp); //default constructor (used by local vars) m_state.indent(fp); fp->write(mangledName.c_str()); fp->write("() { }"); GCNL; //constructor here (used by const tmpVars) m_state.indent(fp); fp->write(mangledName.c_str()); fp->write("(const "); fp->write(getTmpStorageTypeAsString().c_str()); //u32, u64 fp->write(" d) { "); fp->write("write(d); }"); GCNL; //array initialization constructor here (used by const tmpVars); // in C, the array is just a pointer (since not within a struct); if(!isScalar()) { m_state.indent(fp); fp->write(mangledName.c_str()); fp->write("(const u32"); fp->write(" d["); fp->write_decimal_unsigned(UlamType::getTotalNumberOfWords()); fp->write("]) : BVS(d) { }"); GCNL; } //copy constructor here (return by value) m_state.indent(fp); fp->write(mangledName.c_str()); fp->write("(const "); fp->write(mangledName.c_str()); //u32 fp->write("& other) { "); fp->write("this->write"); fp->write("(other."); fp->write("read"); fp->write("()); }"); GCNL; //constructor from ref of same type m_state.indent(fp); fp->write(mangledName.c_str()); fp->write("(const "); fp->write(automangledName.c_str()); fp->write("<EC>& d) { "); //uc consistent with atomref fp->write("this->write("); fp->write("d.read()); }"); GCNL; //default destructor (intentionally left out //for var args native funcs, non-refs, required of a BitStorage UlamType::genGetUlamTypeMangledNameDefinitionForC(fp); m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("};\n"); m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("} //MFM\n"); m_state.indent(fp); fp->write("#endif /*"); fp->write(udstr.c_str()); fp->write(" */\n\n"); } //genUlamTypeMangledDefinitionForC
void UlamTypePrimitive::genUlamTypeMangledAutoDefinitionForC(File * fp) { s32 len = getTotalBitSize(); m_state.m_currentIndentLevel = 0; const std::string automangledName = getUlamTypeImmediateAutoMangledName(); std::ostringstream ud; ud << "Ud_" << automangledName; //d for define (p used for atomicparametrictype) std::string udstr = ud.str(); m_state.indent(fp); fp->write("#ifndef "); fp->write(udstr.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("#define "); fp->write(udstr.c_str()); fp->write("\n"); m_state.indent(fp); fp->write("namespace MFM{\n"); m_state.m_currentIndentLevel++; m_state.indent(fp); fp->write("template<class EC>\n"); m_state.indent(fp); fp->write("struct "); fp->write(automangledName.c_str()); fp->write(" : public UlamRef<EC>\n"); m_state.indent(fp); fp->write("{\n"); m_state.m_currentIndentLevel++; //typedef atomic parameter type inside struct UlamType::genStandardConfigTypedefTypenames(fp, m_state); genUlamTypeAutoReadDefinitionForC(fp); genUlamTypeAutoWriteDefinitionForC(fp); //constructor for ref (auto); wo origin m_state.indent(fp); fp->write(automangledName.c_str()); fp->write("(BitStorage<EC>& targ, u32 idx, const UlamContext<EC>& uc) : UlamRef<EC>(idx, "); fp->write_decimal_unsigned(len); //includes arraysize fp->write("u, targ, NULL, "); //effself is null for primitives if(!isScalar()) fp->write("UlamRef<EC>::ARRAY"); else fp->write("UlamRef<EC>::PRIMITIVE"); fp->write(", uc) { }"); GCNL; //constructor for chain of autorefs (e.g. memberselect with array item) m_state.indent(fp); fp->write(automangledName.c_str()); fp->write("(const UlamRef<EC>& arg, s32 idx) : UlamRef<EC>(arg, idx, "); fp->write_decimal_unsigned(len); //includes arraysize fp->write("u, NULL, "); //effself is null for primitives if(!isScalar()) fp->write("UlamRef<EC>::ARRAY"); else fp->write("UlamRef<EC>::PRIMITIVE"); fp->write(") { }"); GCNL; //copy constructor m_state.indent(fp); fp->write(automangledName.c_str()); fp->write("(const "); fp->write(automangledName.c_str()); //(was UlamRef) fp->write("<EC>& arg) : UlamRef<EC>(arg, 0, arg.GetLen(), NULL, "); if(!isScalar()) fp->write("UlamRef<EC>::ARRAY"); else fp->write("UlamRef<EC>::PRIMITIVE"); fp->write(") { "); fp->write("MFM_API_ASSERT_ARG(arg.GetLen() == "); fp->write_decimal_unsigned(len); //includes arraysize fp->write("); }"); GCNL; //effself is null for primitives //default destructor (intentially left out) //declare away operator= m_state.indent(fp); fp->write(automangledName.c_str()); fp->write("& operator=(const "); fp->write(automangledName.c_str()); fp->write("& rhs); //declare away"); GCNL; m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("};\n"); m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("} //MFM\n"); m_state.indent(fp); fp->write("#endif /*"); fp->write(udstr.c_str()); fp->write(" */\n\n"); } //genUlamTypeMangledAutoDefinitionForC