bool UlamTypePrimitiveUnary::cast(UlamValue & val, UTI typidx) { bool brtn = true; assert(m_state.getUlamTypeByIndex(typidx) == this); UTI valtypidx = val.getUlamValueTypeIdx(); if(UlamType::safeCast(valtypidx) != CAST_CLEAR) //bad|hazy return false; u32 wordsize = getTotalWordSize(); u32 valwordsize = m_state.getTotalWordSize(valtypidx); if(wordsize <= MAXBITSPERINT) { if(valwordsize <= MAXBITSPERINT) brtn = castTo32(val, typidx); else if(valwordsize <= MAXBITSPERLONG) brtn = castTo64(val, typidx); //downcast else m_state.abortGreaterThanMaxBitsPerLong(); } else if(wordsize <= MAXBITSPERLONG) brtn = castTo64(val, typidx); else { std::ostringstream msg; msg << "Casting to an unsupported word size: " << wordsize; msg << ", Value Type and bit size was: "; msg << valtypidx << "," << m_state.getBitSize(valtypidx); msg << " TO: "; msg << typidx << "," << getBitSize(); MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(), msg.str().c_str(), DEBUG); brtn = false; } return brtn; } //cast
const std::string UlamType::castMethodForCodeGen(UTI nodetype) { std::ostringstream rtnMethod; UlamType * nut = m_state.getUlamTypeByIndex(nodetype); //base types e.g. Int, Bool, Unary, Foo, Bar.. u32 sizeByIntBitsToBe = getTotalWordSize(); u32 sizeByIntBits = nut->getTotalWordSize(); if(sizeByIntBitsToBe != sizeByIntBits) { std::ostringstream msg; msg << "Casting different word sizes; " << sizeByIntBits; msg << ", Value Type and size was: " << nut->getUlamTypeName().c_str(); msg << ", to be: " << sizeByIntBitsToBe << " for type: "; msg << getUlamTypeName().c_str(); MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(), msg.str().c_str(), DEBUG); //use the larger word size if(sizeByIntBitsToBe < sizeByIntBits) //downcast using larger sizeByIntBitsToBe = sizeByIntBits; else sizeByIntBits = sizeByIntBitsToBe; } rtnMethod << "_" << nut->getUlamTypeNameOnly().c_str() << sizeByIntBits << "To"; rtnMethod << getUlamTypeNameOnly().c_str() << sizeByIntBitsToBe; return rtnMethod.str(); } //castMethodForCodeGen
s32 UlamTypePrimitiveUnary::bitsizeToConvertTypeTo(ULAMTYPE tobUT) { s32 wordsize = getTotalWordSize(); s32 bitsize = getBitSize(); s32 tobitsize = UNKNOWNSIZE; switch(tobUT) { case Unsigned: tobitsize = (s32) _getLogBase2(bitsize) + 1; //fits into unsigned break; case Int: tobitsize = (s32) _getLogBase2(bitsize) + 1 + 1; break; case Bool: tobitsize = 1; break; case Unary: case Bits: tobitsize = bitsize; //self break; case Void: tobitsize = 0; break; case UAtom: case Class: break; default: m_state.abortUndefinedUlamType(); //std::cerr << "UlamTypePrimitiveUnary convertTypeTo error! " << tobUT << std::endl; }; return (tobitsize > wordsize ? wordsize : tobitsize); } //bitsizeToconvertTypeTo
s32 UlamTypeInt::bitsizeToConvertTypeTo(ULAMTYPE tobUT) { s32 bitsize = getBitSize(); s32 tobitsize = UNKNOWNSIZE; s32 wordsize = getTotalWordSize(); switch(tobUT) { case Unsigned: tobitsize = bitsize; //unsafe break; case Unary: tobitsize = getMax(); break; case Bool: tobitsize = 1; break; case Int: case Bits: tobitsize = bitsize; //self break; case Void: tobitsize = 0; break; case UAtom: case Class: break; default: assert(0); //std::cerr << "UlamTypeInt (convertTo) error! " << tobUT << std::endl; }; return (tobitsize > wordsize ? wordsize : tobitsize); } //bitsizeToConvertTypeTo
bool UlamTypeInt::castTo64(UlamValue & val, UTI typidx) { bool brtn = true; UTI valtypidx = val.getUlamValueTypeIdx(); u32 valwordsize = m_state.getTotalWordSize(valtypidx); u64 data; if(valwordsize == MAXBITSPERINT) data = (u64) val.getImmediateData(m_state); else if(valwordsize == MAXBITSPERLONG) data = val.getImmediateDataLong(m_state); else assert(0); u64 sdata = 0; s32 bitsize = getBitSize(); s32 valbitsize = m_state.getBitSize(valtypidx); ULAMTYPE valtypEnum = m_state.getUlamTypeByIndex(valtypidx)->getUlamTypeEnum(); switch(valtypEnum) { case Int: // casting Int to Int to change bits size sdata = _Int64ToInt64(data, valbitsize, bitsize); break; case Unsigned: // casting Unsigned to Int to change type sdata = _Unsigned64ToInt64(data, valbitsize, bitsize); break; case Bits: // casting Bits to Int to change type sdata = _Bits64ToInt64(data, valbitsize, bitsize); break; case Unary: sdata = _Unary64ToInt64(data, valbitsize, bitsize); break; case Bool: sdata = _Bool64ToInt64(data, valbitsize, bitsize); break; case Void: default: //std::cerr << "UlamTypeInt (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; if(brtn) { u32 wordsize = getTotalWordSize(); //tobe if(wordsize == MAXBITSPERINT) //downcast val = UlamValue::makeImmediate(typidx, (u32) sdata, m_state); //overwrite val else if(wordsize == MAXBITSPERLONG) val = UlamValue::makeImmediateLong(typidx, sdata, m_state); //overwrite val else assert(0); } return brtn; } //castTo64
bool UlamTypePrimitiveUnary::castTo64(UlamValue & val, UTI typidx) { bool brtn = true; UTI valtypidx = val.getUlamValueTypeIdx(); u32 valwordsize = m_state.getTotalWordSize(valtypidx); u64 data; if(valwordsize <= MAXBITSPERINT) data = (u64) val.getImmediateData(m_state); else if(valwordsize <= MAXBITSPERLONG) data = val.getImmediateDataLong(m_state); else m_state.abortGreaterThanMaxBitsPerLong(); s32 bitsize = getBitSize(); s32 valbitsize = m_state.getBitSize(valtypidx); //base types e.g. Int, Bool, Unary, Foo, Bar.. ULAMTYPE valtypEnum = m_state.getUlamTypeByIndex(valtypidx)->getUlamTypeEnum(); switch(valtypEnum) { case Int: // cast from Int->Unary, OR Bool->Unary (same as Bool->Int) data = _Int64ToUnary64(data, valbitsize, bitsize); break; case Unsigned: data = _Unsigned64ToUnary64(data, valbitsize, bitsize); break; case Bool: // Bool -> Unary is the same as Bool -> Int data = _Bool64ToUnary64(data, valbitsize, bitsize); break; case Unary: data = _Unary64ToUnary64(data, valbitsize, bitsize); break; case Bits: break; case Void: default: //std::cerr << "UlamTypePrimitiveUnary (cast) error! Value Type was: " << valtypidx << std::endl; brtn = false; }; if(brtn) { u32 wordsize = getTotalWordSize(); //tobe if(wordsize <= MAXBITSPERINT) //downcast val = UlamValue::makeImmediate(typidx, data, m_state); //overwrite val else if(wordsize <= MAXBITSPERLONG) val = UlamValue::makeImmediateLong(typidx, data, m_state); //overwrite val else m_state.abortGreaterThanMaxBitsPerLong(); } return brtn; } //castTo64
s64 UlamTypePrimitive::getMin(UlamValue& rtnUV, UTI uti) { u32 wordsize = getTotalWordSize(); if(wordsize <= MAXBITSPERINT) rtnUV = UlamValue::makeImmediate(uti, (s32) m_min, m_state); else if(wordsize <= MAXBITSPERLONG) rtnUV = UlamValue::makeImmediateLong(uti, (s64) m_min, m_state); else m_state.abortGreaterThanMaxBitsPerLong(); return m_min; } //getMin (UlamValue)
const std::string UlamType::writeMethodForCodeGen() { std::string method; u32 sizeByIntBits = getTotalWordSize(); switch(sizeByIntBits) { case 0: //e.g. empty quarks case 32: method = "Write"; break; case 64: method = "WriteLong"; break; case 96: method = "WriteBig"; break; default: method = "WriteBV"; //template arg deduced by gcc }; return method; } //writeMethodForCodeGen
u32 UlamType::getTotalNumberOfWords() { return getTotalWordSize()/MAXBITSPERINT; //wordsize was rounded up (no +31 needed) }
const std::string UlamType::getTmpStorageTypeAsString() { return getTmpStorageTypeAsString(getTotalWordSize()); }