| /* |
| Copyright 2019 Alain Dargelas |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /* |
| * File: Value.cpp |
| * Author: alain |
| * |
| * Created on October 29, 2017, 10:33 PM |
| */ |
| #include <string> |
| #include <cmath> |
| #include <cstdint> |
| #include <cstring> |
| #include "Expression/Value.h" |
| |
| using namespace SURELOG; |
| |
| unsigned int Value::nbWords_(unsigned int size) { |
| uint64_t nb = size / 64; |
| if ((nb * 64) != size) nb++; |
| return nb; |
| } |
| |
| SValue::~SValue() {} |
| |
| LValue::~LValue() { delete[] m_valueArray; } |
| |
| StValue::~StValue() {} |
| |
| bool LValue::operator<(const Value& rhs) const { |
| // TODO |
| return true; |
| } |
| |
| bool LValue::operator==(const Value& rhs) const { |
| // TODO |
| return true; |
| } |
| |
| ValueFactory::ValueFactory() : m_headFree(nullptr), m_headInUse(nullptr) {} |
| |
| Value* ValueFactory::newSValue() { return new SValue(); } |
| |
| Value* ValueFactory::newStValue() { return new StValue(); } |
| |
| Value* ValueFactory::newLValue() { |
| if (m_headFree == nullptr) { |
| return new LValue(); |
| } else { |
| LValue* ret = m_headFree; |
| LValue* next = m_headFree->m_next; |
| LValue* prev = m_headFree->m_prev; |
| m_headFree = next; |
| if (prev == next) { |
| m_headFree = nullptr; |
| } else { |
| next->m_prev = prev; |
| prev->m_next = next; |
| } |
| ret->m_prev = nullptr; |
| ret->m_next = nullptr; |
| return ret; |
| } |
| } |
| |
| Value* ValueFactory::newValue(SValue& initVal) { return new SValue(initVal); } |
| |
| Value* ValueFactory::newValue(StValue& initVal) { return new StValue(initVal); } |
| |
| Value* ValueFactory::newValue(LValue& initVal) { |
| if (m_headFree == nullptr) { |
| return new LValue(initVal); |
| } else { |
| LValue* ret = m_headFree; |
| LValue* next = m_headFree->m_next; |
| LValue* prev = m_headFree->m_prev; |
| m_headFree = next; |
| if (prev == next) { |
| m_headFree = nullptr; |
| } else { |
| next->m_prev = prev; |
| prev->m_next = next; |
| } |
| ret->m_prev = nullptr; |
| ret->m_next = nullptr; |
| ret->adjust(&initVal); |
| for (unsigned int i = 0; i < ret->m_nbWords; i++) { |
| ret->m_valueArray[i] = initVal.m_valueArray[i]; |
| } |
| |
| return ret; |
| } |
| } |
| |
| void ValueFactory::deleteValue(Value* value) { |
| if (value->getType() == Value::Type::String) { |
| // TODO: investigate memory corruption |
| // delete (StValue*) value; |
| return; |
| } |
| LValue* val = (LValue*)value; |
| const Value* prev = m_headFree; |
| if (prev == nullptr) { |
| m_headFree = (LValue*)val; |
| m_headFree->m_next = m_headFree; |
| m_headFree->m_prev = m_headFree; |
| } else { |
| LValue* next = m_headFree; |
| LValue* prev = m_headFree->m_prev; |
| next->m_prev = val; |
| prev->m_next = val; |
| val->m_next = next; |
| val->m_prev = prev; |
| m_headFree = val; |
| } |
| } |
| |
| void SValue::set(uint64_t val) { |
| m_value = val; |
| m_size = 64; |
| } |
| void SValue::set(int64_t val) { |
| m_value = val; |
| m_size = 64; |
| } |
| void SValue::set(double val) { |
| m_value = (uint64_t)val; |
| m_size = 64; |
| } |
| void SValue::set(uint64_t val, Type type, unsigned short size) { |
| m_value = val; |
| m_size = size; |
| } |
| |
| void SValue::u_plus(const Value* a) { |
| const SValue* aval = (const SValue*)a; |
| m_size = aval->m_size; |
| m_value = aval->m_value; |
| } |
| |
| void SValue::incr() { m_value++; } |
| |
| void SValue::decr() { m_value--; } |
| |
| void SValue::u_minus(const Value* a) { |
| const SValue* aval = (const SValue*)a; |
| m_size = aval->m_size; |
| m_value = -aval->m_value; |
| } |
| |
| void SValue::u_not(const Value* a) { |
| const SValue* aval = (const SValue*)a; |
| m_size = aval->m_size; |
| m_value = !aval->m_value; |
| } |
| |
| void SValue::u_tilda(const Value* a) { |
| const SValue* aval = (const SValue*)a; |
| m_size = aval->m_size; |
| m_value = ~aval->m_value; |
| } |
| |
| void SValue::plus(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value + bval->m_value; |
| } |
| |
| void SValue::minus(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value - bval->m_value; |
| } |
| |
| void SValue::mult(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value * bval->m_value; |
| } |
| |
| void SValue::div(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value / bval->m_value; |
| } |
| |
| void SValue::mod(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value % bval->m_value; |
| } |
| |
| void SValue::greater(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value > bval->m_value; |
| } |
| |
| void SValue::greater_equal(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value >= bval->m_value; |
| } |
| |
| void SValue::lesser(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value < bval->m_value; |
| } |
| |
| void SValue::lesser_equal(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value <= bval->m_value; |
| } |
| |
| void SValue::equiv(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value == bval->m_value; |
| } |
| |
| void SValue::logAnd(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value && bval->m_value; |
| } |
| |
| void SValue::logOr(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value || bval->m_value; |
| } |
| |
| void SValue::bitwAnd(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value & bval->m_value; |
| } |
| |
| void SValue::bitwOr(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value | bval->m_value; |
| } |
| |
| void SValue::bitwXor(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value ^ bval->m_value; |
| } |
| |
| void SValue::notEqual(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value != bval->m_value; |
| } |
| |
| void SValue::shiftLeft(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value << bval->m_value; |
| } |
| |
| void SValue::shiftRight(const Value* a, const Value* b) { |
| const SValue* aval = (const SValue*)a; |
| const SValue* bval = (const SValue*)b; |
| m_size = (aval->m_size > bval->m_size) ? aval->m_size : bval->m_size; |
| m_value = aval->m_value >> bval->m_value; |
| } |
| |
| unsigned short LValue::getSize() const { |
| unsigned short size = 0; |
| for (int i = 0; i < m_nbWords; i++) { |
| size += m_valueArray[i].m_size; |
| } |
| return size; |
| } |
| |
| LValue::LValue(const LValue& val) |
| : m_type(val.m_type), m_nbWords(val.m_nbWords), |
| m_valueArray(new SValue[val.m_nbWords]), |
| m_prev(nullptr), m_next(nullptr) { |
| for (int i = 0; i < val.m_nbWords; i++) { |
| m_valueArray[i] = val.m_valueArray[i]; |
| } |
| } |
| |
| LValue::LValue(uint64_t val) |
| : m_type(Type::Unsigned), m_nbWords(1), |
| m_valueArray(new SValue[1]), m_prev(nullptr), m_next(nullptr) { |
| m_valueArray[0].m_value = val; |
| m_valueArray[0].m_size = 64; |
| } |
| |
| LValue::LValue(int64_t val) |
| : m_type(Type::Integer), m_nbWords(1), m_valueArray(new SValue[1]), |
| m_prev(nullptr), m_next(nullptr) { |
| m_valueArray[0].m_value = (uint64_t)val; |
| m_valueArray[0].m_size = 64; |
| } |
| |
| LValue::LValue(double val) |
| : m_type(Type::Double), m_nbWords(1), m_valueArray(new SValue[1]), |
| m_prev(nullptr), m_next(nullptr) { |
| m_valueArray[0].m_value = (uint64_t)val; |
| m_valueArray[0].m_size = 64; |
| } |
| |
| LValue::LValue(uint64_t val, Type type, unsigned short size) |
| : m_type(type), m_nbWords(1), m_valueArray(new SValue[1]), |
| m_prev(nullptr), m_next(nullptr) { |
| m_valueArray[0].m_value = val; |
| m_valueArray[0].m_size = size; |
| } |
| |
| void LValue::set(uint64_t val) { |
| m_type = Type::Unsigned; |
| m_nbWords = 1; |
| if (!m_valueArray) m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = val; |
| m_valueArray[0].m_size = 64; |
| } |
| |
| void LValue::set(int64_t val) { |
| m_type = Type::Integer; |
| m_nbWords = 1; |
| if (!m_valueArray) m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = (uint64_t)val; |
| m_valueArray[0].m_size = 64; |
| } |
| |
| void LValue::set(double val) { |
| m_type = Type::Double; |
| m_nbWords = 1; |
| if (!m_valueArray) m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = (uint64_t)val; |
| m_valueArray[0].m_size = 64; |
| } |
| |
| void LValue::set(uint64_t val, Type type, unsigned short size) { |
| m_type = type; |
| m_nbWords = 1; |
| if (!m_valueArray) m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = val; |
| m_valueArray[0].m_size = size; |
| } |
| |
| void LValue::adjust(const Value* a) { |
| m_type = a->getType(); |
| if (a->getNbWords() > getNbWords()) { |
| if (m_valueArray) delete[] m_valueArray; |
| m_nbWords = a->getNbWords(); |
| m_valueArray = new SValue[m_nbWords]; |
| } |
| } |
| |
| void LValue::u_plus(const Value* a) { |
| adjust(a); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = a->getValueUL(i); |
| } |
| } |
| |
| void LValue::incr() { m_valueArray[0].m_value++; } |
| |
| void LValue::decr() { m_valueArray[0].m_value--; } |
| |
| void LValue::u_minus(const Value* a) { |
| adjust(a); |
| for (unsigned short i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = a->getValueUL(i); |
| if (i == (m_nbWords - 1)) { |
| m_valueArray[i].m_value = ~m_valueArray[i].m_value + 1; |
| } |
| } |
| } |
| |
| void LValue::u_not(const Value* a) { |
| adjust(a); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[0].m_value |= a->getValueUL(i); |
| } |
| m_valueArray[0].m_value = !m_valueArray[0].m_value; |
| } |
| |
| void LValue::u_tilda(const Value* a) { |
| adjust(a); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = ~a->getValueUL(i); |
| } |
| } |
| |
| void LValue::plus(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) + b->getValueL(0); |
| } |
| |
| void LValue::minus(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) - b->getValueL(0); |
| } |
| |
| void LValue::mult(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) * b->getValueL(0); |
| } |
| |
| void LValue::div(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| if (b->getValueL(0)) |
| m_valueArray[0].m_value = a->getValueL(0) / b->getValueL(0); |
| else |
| m_valueArray[0].m_value = 69; |
| } |
| |
| void LValue::mod(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) % b->getValueL(0); |
| } |
| |
| void LValue::greater(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) > b->getValueL(0); |
| } |
| |
| void LValue::greater_equal(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) >= b->getValueL(0); |
| } |
| |
| void LValue::lesser(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) < b->getValueL(0); |
| } |
| |
| void LValue::lesser_equal(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) <= b->getValueL(0); |
| } |
| |
| void LValue::equiv(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| if (a->getValueUL(i) != b->getValueUL(i)) { |
| m_valueArray[0].m_value = 0; |
| return; |
| } |
| } |
| m_valueArray[0].m_value = 1; |
| } |
| |
| void LValue::logAnd(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| uint64_t tmp1 = 0; |
| uint64_t tmp2 = 0; |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| tmp1 |= a->getValueUL(i); |
| tmp2 |= b->getValueUL(i); |
| } |
| m_valueArray[0].m_value = tmp1 && tmp2; |
| } |
| |
| void LValue::logOr(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| uint64_t tmp1 = 0; |
| uint64_t tmp2 = 0; |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| tmp1 |= a->getValueUL(i); |
| tmp2 |= b->getValueUL(i); |
| } |
| m_valueArray[0].m_value = tmp1 || tmp2; |
| } |
| |
| void LValue::bitwAnd(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = a->getValueUL(i) & b->getValueUL(i); |
| } |
| } |
| |
| void LValue::bitwOr(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = a->getValueUL(i) | b->getValueUL(i); |
| } |
| } |
| |
| void LValue::bitwXor(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = a->getValueUL(i) ^ b->getValueUL(i); |
| } |
| } |
| |
| void LValue::notEqual(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| equiv(a, b); |
| m_valueArray[0].m_value = !m_valueArray[0].m_value; |
| } |
| |
| void LValue::shiftLeft(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueUL(0) << b->getValueUL(0); |
| } |
| |
| void LValue::shiftRight(const Value* a, const Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueUL(0) >> b->getValueUL(0); |
| } |