/* BitSet64.java * * This class models a 64-bit array, useful for registers and memory representation. * (c) 2006 Salvatore Scellato * * This file is part of the EduMIPS64 project, and is released under the GNU * General Public License. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.edumips64.core; import org.edumips64.utils.Converter; import org.edumips64.utils.IrregularStringOfBitsException; /** This class models a 64-bit array, useful for registers and memory representation. * @author Salvatore Scellato * */ public class BitSet64 extends FixedBitSet { // public final long MAX_DOUBLE = 9223372036854775808L; /** Creates a default new instance of BitSet64. */ public BitSet64() { super(64); } /** Writes an unsigned byte value into this FixedBitSet: the value to be written must be in the range [0, 255], * otherwise an exception will be thrown. * @param value number to be written: must be <CODE>0 <= value <= 255</CODE> * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeByteUnsigned(int value) throws IrregularWriteOperationException { if (value < 0 || value > 255) { throw new IrregularWriteOperationException(); } else { String bits = Converter.positiveIntToBin(value); try { this.reset(false); //dobbiamo scrivere solo negli ultimi 8 bit //ma considerando la dimensione della nuova stringa di bit!! this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } /** Writes a byte value into this FixedBitSet: the value to be written must be in the range [-128, 127], * otherwise an exception will be thrown. * @param value number to be written: must be <CODE>-128 <= value <= 127</CODE> * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeByte(int value) throws IrregularWriteOperationException { if (value < -128 || value > 127) { throw new IrregularWriteOperationException(); } else { String bits = Converter.positiveIntToBin(value); if (value >= 0) { try { this.reset(false); this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo value = -value; try { bits = Converter.twoComplement(bits); //estensione del segno this.reset(true); //il numero Ú negativo, ci vogliono tutti '1' this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } } /** Writes a byte value into this FixedBitSet with an offset: the value to be written must be in the range [-128, 255], * otherwise an exception will be thrown. * @param value number to be written: must be <CODE>-128 <= value <= 255</CODE> * @param offset position to write the byte * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeByte(int value, int offset) throws IrregularWriteOperationException { offset *= 8; offset = 56 - offset; if (value < -128 || value > 255) { throw new IrregularWriteOperationException(); } else { String bits = Converter.positiveIntToBin(8, value); if (value >= 0) { try { this.setBits(bits, offset); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo value = -value; try { bits = Converter.twoComplement(bits); this.setBits(bits, offset); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } } /** Writes an unsigned half-word (16 bit) value into this FixedBitSet: the value to be written must be in the range [0, 65535], * otherwise an exception will be thrown. * @param value number to be written: must be <CODE>0 <= value <= 65535</CODE> * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeHalfUnsigned(int value) throws IrregularWriteOperationException { if (value < 0 || value > 65535) { throw new IrregularWriteOperationException(); } else { String bits = Converter.positiveIntToBin(value); try { this.reset(false); //dobbiamo scrivere solo negli ultimi 16 bit this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } /** Writes a half-word (16 bit) value into this FixedBitSet: the value to be written must be in the range [-32768, 32767], * otherwise an exception will be thrown. * @param value number to be written: must be <CODE>-32768 <= value <= 32767</CODE> * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeHalf(int value) throws IrregularWriteOperationException { if (value < -32768 || value > 32767) { throw new IrregularWriteOperationException(); } else { String bits = Converter.positiveIntToBin(value); if (value >= 0) { try { this.reset(false); this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo value = -value; try { bits = Converter.twoComplement(bits); //estensione del segno this.reset(true); //il numero Ú negativo, ci vogliono tutti '1' this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } } /** Writes a half-word (16 bit) value into this FixedBitSet with a ofset: the value to be written must be in the * range [-32768, 65536], otherwise an exception will be thrown. * @param value number to be written: must be <CODE>-32768 <= value <= 65536</CODE> * @param offset position to write the HalfWord * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation * @throws NotAlignException if offset is not aligned to 16 bit */ public void writeHalf(int value, int offset) throws IrregularWriteOperationException, NotAlignException { offset *= 8; offset = 48 - offset; if (value < -32768 || value > 65536) { throw new IrregularWriteOperationException(); } else if (offset % 16 != 0) { throw new NotAlignException(); } else { String bits = Converter.positiveIntToBin(16, value); if (value >= 0) { try { this.setBits(bits, offset); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo value = -value; try { bits = Converter.twoComplement(bits); this.setBits(bits, offset); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } } /** Writes an unsigned word (32 bit) value into this FixedBitSet: the value to be written must be in the range [0,4294967295], * otherwise an exception will be thrown. * @param value number to be written: must be <CODE>0 <= value <= 4294967295</CODE> * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeWordUnsigned(long value) throws IrregularWriteOperationException, NotAlignException { if (value < 0 || value > 4294967295L) { throw new IrregularWriteOperationException(); } else { String bits = Converter.positiveIntToBin(value); try { this.reset(false); //dobbiamo scrivere solo negli ultimi 32 bit this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } /** Writes a word value (32 bit) into this FixedBitSet: the value to be written must be in the range [-2147483648, 2147483647], * otherwise an exception will be thrown (please note that this range is the same of the java <CODE>int</CODE> type). * @param value number to be written: must be <CODE>-2147483648 <= value <= 2147483647</CODE> */ public void writeWord(int value) throws IrregularWriteOperationException { if (value < -2147483648 || value > 2147483647) { throw new IrregularWriteOperationException(); } String bits = Converter.positiveIntToBin(value); if (value >= 0) { try { this.reset(false); this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo value = -value; try { bits = Converter.twoComplement(bits); //estensione del segno this.reset(true); //il numero Ú negativo, ci vogliono tutti '1' this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } /** Writes a word value (32 bit) into this FixedBitSet with a offset: the value to be written must be in the range [-2147483648, 4294967296], * otherwise an exception will be thrown (please note that this range is the same of the java <CODE>int</CODE> type). * @param value number to be written: must be <CODE>-2147483648 <= value <= 4294967296</CODE> * @param offset position to write the Word * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation * @throws NotAlignException if offset is not aligned to 32 bit */ public void writeWord(long value, int offset) throws IrregularWriteOperationException, NotAlignException { offset *= 8; offset = 32 - offset; if (value < -2147483648 || value > 4294967295L) { throw new IrregularWriteOperationException(); } else if (offset % 32 != 0) { throw new NotAlignException(); } String bits = Converter.positiveIntToBin(32, value); if (value >= 0) { try { this.setBits(bits, offset); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo value = -value; try { bits = Converter.twoComplement(bits); this.setBits(bits, offset); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } /** Writes a double value (64 bit) into this FixedBitSet: the value to be written must be in the range [-2^63, (2^63)-1], * otherwise an exception will be thrown (please note that this range is the same of the java <CODE>long</CODE> type). * @param value number to be written: must be <CODE>2^63 <= value <= (2^63)-1</CODE> * @throws IrregularWriteOperationException if value is not correct or anything else goes wrong during the operation */ public void writeDoubleWord(long value) throws IrregularWriteOperationException { String bits = Converter.positiveIntToBin(value); if (value >= 0) { try { this.reset(false); this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } else { //il numero Ú negativo if (value == -9223372036854775808L) { //questo numero non può essere convertito dalla positiveIntToBin //occorre fare a mano //e mettere il valore "1000000....0000" (tutti zero nel mezzo) this.reset(false); try { this.setBits("1", 0); } catch (IrregularStringOfBitsException e) {} //non può accadere :-) return; } value = -value; try { bits = Converter.positiveIntToBin(value); bits = Converter.twoComplement(bits); //estensione del segno this.reset(true); //il numero Ú negativo, ci vogliono tutti '1' this.setBits(bits, size - bits.length()); } catch (IrregularStringOfBitsException e) { System.err.println("stringa errata: " + bits); e.printStackTrace(); throw new IrregularWriteOperationException(); } } } /** Get the value of the one Byte of bitset by position * @param offset position to read the byte * @return the value of the byte */ public int readByte(int offset) { offset *= 8; offset = 56 - offset; String val = getBinString().substring(offset, offset + 8); try { return Converter.binToInt(val, false); } catch (IrregularStringOfBitsException e) { System.err.println(e); e.printStackTrace(); throw new RuntimeException(e); } } /** Get the value Unsigned of the one Byte of bitset by position * @param offset position to read the byte * @return the value Unsigned of the byte */ public int readByteUnsigned(int offset) { offset *= 8; offset = 56 - offset; String val = getBinString().substring(offset, offset + 8); try { return Converter.binToInt(val, true); } catch (IrregularStringOfBitsException e) { System.err.println(e); e.printStackTrace(); throw new RuntimeException(e); } } /** Get the value of the one HalfWord of bitset by position * @param offset position to read the byte * @return the value of the byte * @throws NotAlignException if offset is not aligned to 16 bit */ public int readHalf(int offset) throws IrregularStringOfBitsException, NotAlignException { if (offset % 2 != 0) { throw new NotAlignException(); } offset *= 8; offset = 48 - offset; String val = getBinString().substring(offset, offset + 16); try { return Converter.binToInt(val, false); } catch (IrregularStringOfBitsException e) { System.err.println(e); e.printStackTrace(); throw new RuntimeException(e); } } /** Get the value Unsigned of the one HalfWord of bitset by position * @param offset position to read the byte * @return the value Unsigned of the byte * @throws NotAlignException if offset is not aligned to 16 bit */ public int readHalfUnsigned(int offset) throws NotAlignException { if (offset % 2 != 0) { throw new NotAlignException(); } offset *= 8; offset = 48 - offset; String val = getBinString().substring(offset, offset + 16); try { return Converter.binToInt(val, true); } catch (IrregularStringOfBitsException e) { System.err.println(e); e.printStackTrace(); throw new RuntimeException(e); } } /** Get the value of the one Word of bitset by position * @param offset position to read the byte * @return the value of the byte * @throws NotAlignException if offset is not aligned to 32 bit */ public int readWord(int offset) throws NotAlignException { if (offset % 4 != 0) { throw new NotAlignException(); } offset *= 8; offset = 32 - offset; String val = getBinString().substring(offset, offset + 32); try { return Converter.binToInt(val, false); } catch (IrregularStringOfBitsException e) { System.err.println(e); e.printStackTrace(); throw new RuntimeException(e); } } /** Get the value Unsigned of the one Word of bitset by position * @param offset position to read the byte * @return the value Unsigned of the byte * @throws NotAlignException if offset is not aligned to 32 bit */ public long readWordUnsigned(int offset) throws NotAlignException { if (offset % 4 != 0) { throw new NotAlignException(); } offset *= 8; offset = 32 - offset; String val = getBinString().substring(offset, offset + 32); try { return Converter.binToLong(val, true); } catch (IrregularStringOfBitsException e) { System.err.println(e); e.printStackTrace(); throw new RuntimeException(e); } } }