| /* |
| 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<(Value& rhs) { |
| // TODO |
| return true; |
| } |
| |
| bool LValue::operator==(Value& rhs) { |
| // TODO |
| return true; |
| } |
| |
| ValueFactory::ValueFactory() { |
| m_headFree = NULL; |
| m_headInUse = NULL; |
| } |
| |
| Value* ValueFactory::newSValue() { return new SValue(); } |
| |
| Value* ValueFactory::newStValue() { return new StValue(); } |
| |
| Value* ValueFactory::newLValue() { |
| if (m_headFree == NULL) { |
| 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 = NULL; |
| } else { |
| next->m_prev = prev; |
| prev->m_next = next; |
| } |
| ret->m_prev = NULL; |
| ret->m_next = NULL; |
| 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 == NULL) { |
| 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 = NULL; |
| } else { |
| next->m_prev = prev; |
| prev->m_next = next; |
| } |
| ret->m_prev = NULL; |
| ret->m_next = NULL; |
| 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::String) { |
| // TODO: investigate memory corruption |
| // delete (StValue*) value; |
| return; |
| } |
| LValue* val = (LValue*)value; |
| Value* prev = m_headFree; |
| if (prev == NULL) { |
| 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, ValueType type, unsigned short size) { |
| m_value = val; |
| m_size = size; |
| } |
| |
| void SValue::u_plus(Value* a) { |
| SValue* aval = (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(Value* a) { |
| SValue* aval = (SValue*)a; |
| m_size = aval->m_size; |
| m_value = -aval->m_value; |
| } |
| |
| void SValue::u_not(Value* a) { |
| SValue* aval = (SValue*)a; |
| m_size = aval->m_size; |
| m_value = !aval->m_value; |
| } |
| |
| void SValue::u_tilda(Value* a) { |
| SValue* aval = (SValue*)a; |
| m_size = aval->m_size; |
| m_value = ~aval->m_value; |
| } |
| |
| void SValue::plus(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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(Value* a, Value* b) { |
| SValue* aval = (SValue*)a; |
| SValue* bval = (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() { |
| unsigned short size = 0; |
| for (int i = 0; i < m_nbWords; i++) { |
| size += m_valueArray[i].m_size; |
| } |
| return size; |
| } |
| |
| LValue::LValue(LValue& val) { |
| m_type = val.m_type; |
| m_prev = NULL; |
| m_next = NULL; |
| m_nbWords = val.m_nbWords; |
| m_valueArray = new SValue[val.m_nbWords]; |
| for (int i = 0; i < val.m_nbWords; i++) { |
| m_valueArray[i] = val.m_valueArray[i]; |
| } |
| } |
| |
| LValue::LValue(uint64_t val) { |
| m_type = Unsigned; |
| m_nbWords = 1; |
| m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = val; |
| m_valueArray[0].m_size = 64; |
| m_prev = NULL; |
| m_next = NULL; |
| } |
| |
| LValue::LValue(int64_t val) { |
| m_type = Integer; |
| m_nbWords = 1; |
| m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = (uint64_t)val; |
| m_valueArray[0].m_size = 64; |
| m_prev = NULL; |
| m_next = NULL; |
| } |
| |
| LValue::LValue(double val) { |
| m_type = Double; |
| m_nbWords = 1; |
| m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = (uint64_t)val; |
| m_valueArray[0].m_size = 64; |
| m_prev = NULL; |
| m_next = NULL; |
| } |
| |
| LValue::LValue(uint64_t val, ValueType type, unsigned short size) { |
| m_type = type; |
| m_nbWords = 1; |
| m_valueArray = new SValue[1]; |
| m_valueArray[0].m_value = val; |
| m_valueArray[0].m_size = size; |
| m_prev = NULL; |
| m_next = NULL; |
| } |
| |
| void LValue::set(uint64_t val) { |
| m_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 = 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 = 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, ValueType 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(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(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(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(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(Value* a) { |
| adjust(a); |
| for (unsigned int i = 0; i < m_nbWords; i++) { |
| m_valueArray[i].m_value = ~a->getValueUL(i); |
| } |
| } |
| |
| void LValue::plus(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) + b->getValueL(0); |
| } |
| |
| void LValue::minus(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) - b->getValueL(0); |
| } |
| |
| void LValue::mult(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) * b->getValueL(0); |
| } |
| |
| void LValue::div(Value* a, 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(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) % b->getValueL(0); |
| } |
| |
| void LValue::greater(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) > b->getValueL(0); |
| } |
| |
| void LValue::greater_equal(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) >= b->getValueL(0); |
| } |
| |
| void LValue::lesser(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) < b->getValueL(0); |
| } |
| |
| void LValue::lesser_equal(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueL(0) <= b->getValueL(0); |
| } |
| |
| void LValue::equiv(Value* a, 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(Value* a, 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(Value* a, 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(Value* a, 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(Value* a, 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(Value* a, 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(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| equiv(a, b); |
| m_valueArray[0].m_value = !m_valueArray[0].m_value; |
| } |
| |
| void LValue::shiftLeft(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueUL(0) << b->getValueUL(0); |
| } |
| |
| void LValue::shiftRight(Value* a, Value* b) { |
| adjust(a); |
| adjust(b); |
| m_valueArray[0].m_value = a->getValueUL(0) >> b->getValueUL(0); |
| } |