mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-27 23:17:03 +08:00
Merge branch 'GP-1379_ghidra1_FloatDataTypeValues' (Closes #4853)
This commit is contained in:
+3
@@ -27,6 +27,7 @@ import ghidra.dbg.target.TargetDataTypeMember;
|
|||||||
import ghidra.dbg.target.TargetNamedDataType;
|
import ghidra.dbg.target.TargetNamedDataType;
|
||||||
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
|
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.AbstractFloatDataType;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
public class TargetDataTypeConverter {
|
public class TargetDataTypeConverter {
|
||||||
@@ -481,6 +482,8 @@ public class TargetDataTypeConverter {
|
|||||||
case SINT:
|
case SINT:
|
||||||
return AbstractIntegerDataType.getSignedDataType(tPrimitive.getLength(), dtm);
|
return AbstractIntegerDataType.getSignedDataType(tPrimitive.getLength(), dtm);
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
|
// TODO: lookup by length must use "raw" encoding size since "aligned" lengths
|
||||||
|
// may be duplicated across different float types.
|
||||||
return AbstractFloatDataType.getFloatDataType(tPrimitive.getLength(), dtm);
|
return AbstractFloatDataType.getFloatDataType(tPrimitive.getLength(), dtm);
|
||||||
case COMPLEX:
|
case COMPLEX:
|
||||||
return AbstractComplexDataType.getComplexDataType(tPrimitive.getLength(), dtm);
|
return AbstractComplexDataType.getComplexDataType(tPrimitive.getLength(), dtm);
|
||||||
|
|||||||
+1
-1
@@ -23,8 +23,8 @@ import db.DBRecord;
|
|||||||
import ghidra.program.database.data.DataTypeUtilities;
|
import ghidra.program.database.data.DataTypeUtilities;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.AddressSpace;
|
||||||
import ghidra.program.model.data.AbstractFloatDataType;
|
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
|
import ghidra.program.model.data.floats.AbstractFloatDataType;
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.Register;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.pcode.Varnode;
|
import ghidra.program.model.pcode.Varnode;
|
||||||
|
|||||||
+37
-8
@@ -126,22 +126,51 @@ public class CreateDataBackgroundCmd extends BackgroundCommand {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Address alignAddress(Address addr, int alignment) {
|
||||||
|
if (addr == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long mod = addr.getOffset() % alignment;
|
||||||
|
if (mod == 0) {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return addr.addNoWrap(alignment - mod);
|
||||||
|
}
|
||||||
|
catch (AddressOverflowException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void createData(Address start, Address end, DataType dataType, Program p,
|
private void createData(Address start, Address end, DataType dataType, Program p,
|
||||||
TaskMonitor monitor) throws AddressOverflowException, CodeUnitInsertionException {
|
TaskMonitor monitor) throws CodeUnitInsertionException {
|
||||||
|
|
||||||
|
int alignment = 1;
|
||||||
|
if (newDataType.getLength() != newDataType.getAlignedLength()) {
|
||||||
|
// datatypes whose length does not match their aligned-length must
|
||||||
|
// be properly aligned to account for padding (e.g., x86-32 80-bit floats)
|
||||||
|
alignment = newDataType.getAlignment();
|
||||||
|
}
|
||||||
|
|
||||||
|
int initialProgress = bytesApplied;
|
||||||
|
|
||||||
Listing listing = p.getListing();
|
Listing listing = p.getListing();
|
||||||
listing.clearCodeUnits(start, end, false);
|
listing.clearCodeUnits(start, end, false);
|
||||||
int length = (int) end.subtract(start) + 1;
|
Address nextAddr = alignAddress(start, alignment);
|
||||||
while (start.compareTo(end) <= 0) {
|
int length = (int) end.subtract(nextAddr) + 1;
|
||||||
|
while (nextAddr != null && nextAddr.compareTo(end) <= 0) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data d = listing.createData(start, dataType, length);
|
Data d = listing.createData(nextAddr, dataType, length);
|
||||||
int dataLen = d.getLength();
|
Address maxDataAddr = d.getMaxAddress();
|
||||||
start = start.addNoWrap(dataLen);
|
bytesApplied = initialProgress + (int) maxDataAddr.subtract(start) + 1;
|
||||||
length -= dataLen;
|
nextAddr = alignAddress(maxDataAddr.next(), alignment);
|
||||||
bytesApplied += dataLen;
|
if (nextAddr != null) {
|
||||||
|
length = (int) end.subtract(nextAddr) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
monitor.setProgress(bytesApplied);
|
monitor.setProgress(bytesApplied);
|
||||||
if (++numDataCreated % 10000 == 0) {
|
if (++numDataCreated % 10000 == 0) {
|
||||||
|
|||||||
+1
-1
@@ -133,7 +133,7 @@ public class CreateDataInStructureBackgroundCmd extends BackgroundCommand {
|
|||||||
// MemBuffer memBuf = new ProgramStructureProviderContext(program,addr,
|
// MemBuffer memBuf = new ProgramStructureProviderContext(program,addr,
|
||||||
// struct, struct.getComponent(index).getOffset());
|
// struct, struct.getComponent(index).getOffset());
|
||||||
DataTypeInstance dti =
|
DataTypeInstance dti =
|
||||||
DataTypeInstance.getDataTypeInstance(newDataType, length);
|
DataTypeInstance.getDataTypeInstance(newDataType, length, true);
|
||||||
if (dti == null || dti.getLength() > length) {
|
if (dti == null || dti.getLength() > length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -114,7 +114,8 @@ public class CreateDataInStructureCmd implements Command {
|
|||||||
else {
|
else {
|
||||||
// MemBuffer memBuf = new ProgramStructureProviderContext(program,addr,
|
// MemBuffer memBuf = new ProgramStructureProviderContext(program,addr,
|
||||||
// struct, dataComp.getParentOffset());
|
// struct, dataComp.getParentOffset());
|
||||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(newDataType, -1);
|
DataTypeInstance dti =
|
||||||
|
DataTypeInstance.getDataTypeInstance(newDataType, -1, true);
|
||||||
struct.replace(index, dti.getDataType(), dti.getLength());
|
struct.replace(index, dti.getDataType(), dti.getLength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -212,7 +212,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
DataType resultDt = DataUtilities.reconcileAppliedDataType(currentDt, dt, true);
|
DataType resultDt = DataUtilities.reconcileAppliedDataType(currentDt, dt, true);
|
||||||
int resultLen = resultDt.getLength();
|
int resultLen = resultDt.getAlignedLength();
|
||||||
|
|
||||||
if (resultDt instanceof Dynamic) {
|
if (resultDt instanceof Dynamic) {
|
||||||
resultLen = DataTypeHelper.requestDtSize(getProvider(), resultDt.getDisplayName(),
|
resultLen = DataTypeHelper.requestDtSize(getProvider(), resultDt.getDisplayName(),
|
||||||
@@ -222,7 +222,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
throw new InvalidDataTypeException("Data types of size 0 are not allowed.");
|
throw new InvalidDataTypeException("Data types of size 0 are not allowed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return DataTypeInstance.getDataTypeInstance(resultDt, resultLen);
|
return DataTypeInstance.getDataTypeInstance(resultDt, resultLen, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1172,7 +1172,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
dtName = dt.getDisplayName();
|
dtName = dt.getDisplayName();
|
||||||
if (dtString.equals(dtName)) {
|
if (dtString.equals(dtName)) {
|
||||||
return DataTypeInstance.getDataTypeInstance(element.getDataType(),
|
return DataTypeInstance.getDataTypeInstance(element.getDataType(),
|
||||||
element.getLength());
|
element.getLength(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1204,7 +1204,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||||||
if (maxLength > 0 && newLength > maxLength) {
|
if (maxLength > 0 && newLength > maxLength) {
|
||||||
throw new UsrException(newDt.getDisplayName() + " doesn't fit.");
|
throw new UsrException(newDt.getDisplayName() + " doesn't fit.");
|
||||||
}
|
}
|
||||||
return DataTypeInstance.getDataTypeInstance(newDt, newLength);
|
return DataTypeInstance.getDataTypeInstance(newDt, newLength, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused") // the exception is thrown by subclasses
|
@SuppressWarnings("unused") // the exception is thrown by subclasses
|
||||||
|
|||||||
+2
-1
@@ -570,7 +570,8 @@ abstract class CompositeViewerModel extends AbstractTableModel
|
|||||||
else if (columnIndex == getDataTypeColumn()) {
|
else if (columnIndex == getDataTypeColumn()) {
|
||||||
DataType dt = dtc.getDataType();
|
DataType dt = dtc.getDataType();
|
||||||
int dtLen = dt.getLength();
|
int dtLen = dt.getLength();
|
||||||
return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength());
|
return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength(),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
else if (columnIndex == getNameColumn()) {
|
else if (columnIndex == getNameColumn()) {
|
||||||
value = dtc.getFieldName();
|
value = dtc.getFieldName();
|
||||||
|
|||||||
+3
-3
@@ -146,7 +146,7 @@ public class DataTypeHelper {
|
|||||||
throw new InvalidDataTypeException(
|
throw new InvalidDataTypeException(
|
||||||
"Data type " + dt.getDisplayName() + " has no size and is not allowed.");
|
"Data type " + dt.getDisplayName() + " has no size and is not allowed.");
|
||||||
}
|
}
|
||||||
return DataTypeInstance.getDataTypeInstance(dt, dtLen);
|
return DataTypeInstance.getDataTypeInstance(dt, dtLen, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int requestDtSize(CompositeEditorProvider provider, String dtName,
|
public static int requestDtSize(CompositeEditorProvider provider, String dtName,
|
||||||
@@ -203,7 +203,7 @@ public class DataTypeHelper {
|
|||||||
int maxBytes = model.getMaxReplaceLength(index);
|
int maxBytes = model.getMaxReplaceLength(index);
|
||||||
return requestBytes(model, dt, maxBytes);
|
return requestBytes(model, dt, maxBytes);
|
||||||
}
|
}
|
||||||
return DataTypeInstance.getDataTypeInstance(dt, length);
|
return DataTypeInstance.getDataTypeInstance(dt, length, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataTypeInstance requestBytes(CompositeEditorModel model, DataType dt,
|
public static DataTypeInstance requestBytes(CompositeEditorModel model, DataType dt,
|
||||||
@@ -228,7 +228,7 @@ public class DataTypeHelper {
|
|||||||
|
|
||||||
if (size >= 1) {
|
if (size >= 1) {
|
||||||
model.setLastNumBytes(size);
|
model.setLastNumBytes(size);
|
||||||
return DataTypeInstance.getDataTypeInstance(dt, size);
|
return DataTypeInstance.getDataTypeInstance(dt, size, true);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -59,7 +59,8 @@ public class InsertUndefinedAction extends CompositeEditorTableAction {
|
|||||||
DataType undefinedDt =
|
DataType undefinedDt =
|
||||||
model.viewComposite.isPackingEnabled() ? Undefined1DataType.dataType
|
model.viewComposite.isPackingEnabled() ? Undefined1DataType.dataType
|
||||||
: DataType.DEFAULT;
|
: DataType.DEFAULT;
|
||||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(undefinedDt, -1);
|
DataTypeInstance dti =
|
||||||
|
DataTypeInstance.getDataTypeInstance(undefinedDt, -1, false);
|
||||||
model.insert(index, dti.getDataType(), dti.getLength());
|
model.insert(index, dti.getDataType(), dti.getLength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -161,7 +161,8 @@ class StructureEditorModel extends CompEditorModel {
|
|||||||
else if (columnIndex == getDataTypeColumn()) {
|
else if (columnIndex == getDataTypeColumn()) {
|
||||||
DataType dt = dtc.getDataType();
|
DataType dt = dtc.getDataType();
|
||||||
int dtLen = dt.getLength();
|
int dtLen = dt.getLength();
|
||||||
return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength());
|
return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength(),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
else if (columnIndex == getNameColumn()) {
|
else if (columnIndex == getNameColumn()) {
|
||||||
value = dtc.getFieldName();
|
value = dtc.getFieldName();
|
||||||
|
|||||||
+9
-6
@@ -141,7 +141,7 @@ class CreateArrayAction extends ListingContextAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int length = sel.getByteLength();
|
int length = sel.getByteLength();
|
||||||
int numElements = length / dt.getLength();
|
int numElements = length / dt.getAlignedLength();
|
||||||
|
|
||||||
Command cmd = new CreateArrayInStructureCmd(from.getAddress(), numElements, dt,
|
Command cmd = new CreateArrayInStructureCmd(from.getAddress(), numElements, dt,
|
||||||
from.getComponentPath());
|
from.getComponentPath());
|
||||||
@@ -161,7 +161,7 @@ class CreateArrayAction extends ListingContextAction {
|
|||||||
}
|
}
|
||||||
length += dtc.getLength();
|
length += dtc.getLength();
|
||||||
}
|
}
|
||||||
return length / dt.getLength();
|
return length / dt.getAlignedLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxElements(Structure struct, int index, DataType dt) {
|
private int getMaxElements(Structure struct, int index, DataType dt) {
|
||||||
@@ -171,7 +171,7 @@ class CreateArrayAction extends ListingContextAction {
|
|||||||
DataTypeComponent dtc = struct.getComponent(index++);
|
DataTypeComponent dtc = struct.getComponent(index++);
|
||||||
length += dtc.getLength();
|
length += dtc.getLength();
|
||||||
}
|
}
|
||||||
return length / dt.getLength();
|
return length / dt.getAlignedLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createArrayAtAddress(Program program, Address addr) {
|
private void createArrayAtAddress(Program program, Address addr) {
|
||||||
@@ -210,10 +210,13 @@ class CreateArrayAction extends ListingContextAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DataType dt = data.getDataType();
|
DataType dt = data.getDataType();
|
||||||
int dtLength = data.getLength();
|
int elementLength = data.getLength();
|
||||||
|
if (!(dt instanceof Dynamic)) {
|
||||||
|
elementLength = dt.getAlignedLength();
|
||||||
|
}
|
||||||
int length = (int) range.getLength();
|
int length = (int) range.getLength();
|
||||||
int numElements = length / dtLength;
|
int numElements = length / elementLength;
|
||||||
CreateArrayCmd cmd = new CreateArrayCmd(addr, numElements, dt, dtLength);
|
CreateArrayCmd cmd = new CreateArrayCmd(addr, numElements, dt, elementLength);
|
||||||
if (!tool.execute(cmd, program)) {
|
if (!tool.execute(cmd, program)) {
|
||||||
tool.setStatusInfo(cmd.getStatusMsg());
|
tool.setStatusInfo(cmd.getStatusMsg());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ public class DataPlugin extends Plugin implements DataService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DataTypeInstance dataTypeInstance = DataTypeInstance.getDataTypeInstance(dataType,
|
DataTypeInstance dataTypeInstance = DataTypeInstance.getDataTypeInstance(dataType,
|
||||||
new DumbMemBufferImpl(program.getMemory(), start));
|
new DumbMemBufferImpl(program.getMemory(), start), false);
|
||||||
if (dataTypeInstance == null) {
|
if (dataTypeInstance == null) {
|
||||||
tool.setStatusInfo("Unallowed data type at " + start + ": " + dataType.getName());
|
tool.setStatusInfo("Unallowed data type at " + start + ": " + dataType.getName());
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
-494
@@ -1,494 +0,0 @@
|
|||||||
/* ###
|
|
||||||
* IP: GHIDRA
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
package ghidra.app.plugin.core.datamgr;
|
|
||||||
|
|
||||||
import java.awt.event.*;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
|
||||||
import javax.swing.event.ChangeListener;
|
|
||||||
|
|
||||||
import docking.widgets.checkbox.GCheckBox;
|
|
||||||
import docking.widgets.label.GLabel;
|
|
||||||
import ghidra.program.model.data.DataOrganizationImpl;
|
|
||||||
import ghidra.util.layout.PairLayout;
|
|
||||||
|
|
||||||
public class DataOrganizationPanel extends JPanel {
|
|
||||||
|
|
||||||
JCheckBox charIsSignedCheckbox;
|
|
||||||
JTextField charSizeComponent;
|
|
||||||
JTextField wcharSizeComponent;
|
|
||||||
JTextField shortSizeComponent;
|
|
||||||
JTextField integerSizeComponent;
|
|
||||||
JTextField longSizeComponent;
|
|
||||||
JTextField longLongSizeComponent;
|
|
||||||
JTextField floatSizeComponent;
|
|
||||||
JTextField doubleSizeComponent;
|
|
||||||
JTextField longDoubleSizeComponent;
|
|
||||||
|
|
||||||
JTextField absoluteMaxAlignComponent;
|
|
||||||
JTextField machineAlignComponent;
|
|
||||||
JTextField defaultAlignComponent;
|
|
||||||
JTextField pointerAlignComponent;
|
|
||||||
|
|
||||||
DataOrganizationImpl dataOrganization;
|
|
||||||
|
|
||||||
public DataOrganizationPanel() {
|
|
||||||
super(new PairLayout(3, 5));
|
|
||||||
setUpAbsoluteMaxAlignment();
|
|
||||||
setUpMachineAlignment();
|
|
||||||
setUpDefaultAlignment();
|
|
||||||
setUpPointerAlignment();
|
|
||||||
setUpSignedChar();
|
|
||||||
setUpCharSize();
|
|
||||||
setUpWideCharSize();
|
|
||||||
setUpShortSize();
|
|
||||||
setUpIntegerSize();
|
|
||||||
setUpLongSize();
|
|
||||||
setUpLongLongSize();
|
|
||||||
setUpFloatSize();
|
|
||||||
setUpDoubleSize();
|
|
||||||
setUpLongDoubleSize();
|
|
||||||
|
|
||||||
add(new GLabel(""));
|
|
||||||
add(new GLabel(""));
|
|
||||||
add(new GLabel("Absolute Max Alignment"));
|
|
||||||
add(absoluteMaxAlignComponent);
|
|
||||||
add(new GLabel("Machine Alignment"));
|
|
||||||
add(machineAlignComponent);
|
|
||||||
add(new GLabel("Default Alignment"));
|
|
||||||
add(defaultAlignComponent);
|
|
||||||
add(new GLabel("Default Pointer Alignment"));
|
|
||||||
add(pointerAlignComponent);
|
|
||||||
|
|
||||||
add(new GLabel(""));
|
|
||||||
add(new GLabel(""));
|
|
||||||
add(new GLabel("Signed-Char:"));
|
|
||||||
add(charIsSignedCheckbox);
|
|
||||||
add(new GLabel("Char Size"));
|
|
||||||
add(charSizeComponent);
|
|
||||||
add(new GLabel("Wide-Char Size"));
|
|
||||||
add(wcharSizeComponent);
|
|
||||||
add(new GLabel("Short Size"));
|
|
||||||
add(shortSizeComponent);
|
|
||||||
add(new GLabel("Integer Size"));
|
|
||||||
add(integerSizeComponent);
|
|
||||||
add(new GLabel("Long Size"));
|
|
||||||
add(longSizeComponent);
|
|
||||||
add(new GLabel("LongLong Size"));
|
|
||||||
add(longLongSizeComponent);
|
|
||||||
add(new GLabel("Float Size"));
|
|
||||||
add(floatSizeComponent);
|
|
||||||
add(new GLabel("Double Size"));
|
|
||||||
add(doubleSizeComponent);
|
|
||||||
add(new GLabel("LongDouble Size"));
|
|
||||||
add(longDoubleSizeComponent);
|
|
||||||
add(new GLabel(""));
|
|
||||||
add(new GLabel(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrganization(DataOrganizationImpl dataOrganization) {
|
|
||||||
this.dataOrganization = dataOrganization;
|
|
||||||
|
|
||||||
int absoluteMaxAlignment = dataOrganization.getAbsoluteMaxAlignment();
|
|
||||||
int machineAlignment = dataOrganization.getMachineAlignment();
|
|
||||||
int defaultAlignment = dataOrganization.getDefaultAlignment();
|
|
||||||
int defaultPointerAlignment = dataOrganization.getDefaultPointerAlignment();
|
|
||||||
|
|
||||||
int charSize = dataOrganization.getCharSize();
|
|
||||||
int wcharSize = dataOrganization.getWideCharSize();
|
|
||||||
int shortSize = dataOrganization.getShortSize();
|
|
||||||
int integerSize = dataOrganization.getIntegerSize();
|
|
||||||
int longSize = dataOrganization.getLongSize();
|
|
||||||
int longLongSize = dataOrganization.getLongLongSize();
|
|
||||||
int floatSize = dataOrganization.getFloatSize();
|
|
||||||
int doubleSize = dataOrganization.getDoubleSize();
|
|
||||||
int longDoubleSize = dataOrganization.getLongDoubleSize();
|
|
||||||
|
|
||||||
String maxAlignString =
|
|
||||||
(absoluteMaxAlignment == 0) ? "none" : Integer.toString(absoluteMaxAlignment);
|
|
||||||
absoluteMaxAlignComponent.setText(maxAlignString);
|
|
||||||
machineAlignComponent.setText(Integer.toString(machineAlignment));
|
|
||||||
defaultAlignComponent.setText(Integer.toString(defaultAlignment));
|
|
||||||
pointerAlignComponent.setText(Integer.toString(defaultPointerAlignment));
|
|
||||||
|
|
||||||
charSizeComponent.setText(Integer.toString(charSize));
|
|
||||||
wcharSizeComponent.setText(Integer.toString(wcharSize));
|
|
||||||
shortSizeComponent.setText(Integer.toString(shortSize));
|
|
||||||
integerSizeComponent.setText(Integer.toString(integerSize));
|
|
||||||
longSizeComponent.setText(Integer.toString(longSize));
|
|
||||||
longLongSizeComponent.setText(Integer.toString(longLongSize));
|
|
||||||
floatSizeComponent.setText(Integer.toString(floatSize));
|
|
||||||
doubleSizeComponent.setText(Integer.toString(doubleSize));
|
|
||||||
longDoubleSizeComponent.setText(Integer.toString(longDoubleSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpSignedChar() {
|
|
||||||
charIsSignedCheckbox = new GCheckBox();
|
|
||||||
charIsSignedCheckbox.addChangeListener(new ChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void stateChanged(ChangeEvent e) {
|
|
||||||
updateSignedChar();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpCharSize() {
|
|
||||||
charSizeComponent = new JTextField(3);
|
|
||||||
charSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedCharSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
charSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedCharSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpWideCharSize() {
|
|
||||||
wcharSizeComponent = new JTextField(3);
|
|
||||||
wcharSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedWideCharSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
wcharSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedWideCharSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpShortSize() {
|
|
||||||
shortSizeComponent = new JTextField(3);
|
|
||||||
shortSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedShortSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
shortSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedShortSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpIntegerSize() {
|
|
||||||
integerSizeComponent = new JTextField(3);
|
|
||||||
integerSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedIntegerSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
integerSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedIntegerSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpLongSize() {
|
|
||||||
longSizeComponent = new JTextField(3);
|
|
||||||
longSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedLongSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
longSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedLongSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpLongLongSize() {
|
|
||||||
longLongSizeComponent = new JTextField(3);
|
|
||||||
longLongSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedLongLongSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
longLongSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedLongLongSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpFloatSize() {
|
|
||||||
floatSizeComponent = new JTextField(3);
|
|
||||||
floatSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedFloatSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
floatSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedFloatSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpDoubleSize() {
|
|
||||||
doubleSizeComponent = new JTextField(3);
|
|
||||||
doubleSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedDoubleSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
doubleSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedDoubleSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpLongDoubleSize() {
|
|
||||||
longDoubleSizeComponent = new JTextField(3);
|
|
||||||
longDoubleSizeComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedLongDoubleSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
longDoubleSizeComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedLongDoubleSize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpAbsoluteMaxAlignment() {
|
|
||||||
absoluteMaxAlignComponent = new JTextField(3);
|
|
||||||
absoluteMaxAlignComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedAbsoluteMaxAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
absoluteMaxAlignComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedAbsoluteMaxAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpMachineAlignment() {
|
|
||||||
machineAlignComponent = new JTextField(3);
|
|
||||||
machineAlignComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedMachineAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
machineAlignComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedMachineAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpDefaultAlignment() {
|
|
||||||
defaultAlignComponent = new JTextField(3);
|
|
||||||
defaultAlignComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedDefaultAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
defaultAlignComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedDefaultAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpPointerAlignment() {
|
|
||||||
pointerAlignComponent = new JTextField(3);
|
|
||||||
pointerAlignComponent.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
updatedDefaultPointerAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pointerAlignComponent.addFocusListener(new FocusListener() {
|
|
||||||
@Override
|
|
||||||
public void focusGained(FocusEvent e) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void focusLost(FocusEvent e) {
|
|
||||||
updatedDefaultPointerAlignment();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateSignedChar() {
|
|
||||||
boolean isSigned = charIsSignedCheckbox.isSelected();
|
|
||||||
dataOrganization.setCharIsSigned(isSigned);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedCharSize() {
|
|
||||||
int charSize = Integer.decode(charSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setCharSize(charSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedWideCharSize() {
|
|
||||||
int wcharSize = Integer.decode(wcharSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setWideCharSize(wcharSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedShortSize() {
|
|
||||||
int shortSize = Integer.decode(shortSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setShortSize(shortSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedIntegerSize() {
|
|
||||||
int integerSize = Integer.decode(integerSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setIntegerSize(integerSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedLongSize() {
|
|
||||||
int longSize = Integer.decode(longSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setLongSize(longSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedLongLongSize() {
|
|
||||||
int longLongSize = Integer.decode(longLongSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setLongLongSize(longLongSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedFloatSize() {
|
|
||||||
int floatSize = Integer.decode(floatSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setFloatSize(floatSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedDoubleSize() {
|
|
||||||
int doubleSize = Integer.decode(doubleSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setDoubleSize(doubleSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedLongDoubleSize() {
|
|
||||||
int longDoubleSize = Integer.decode(longDoubleSizeComponent.getText()).intValue();
|
|
||||||
dataOrganization.setLongDoubleSize(longDoubleSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedAbsoluteMaxAlignment() {
|
|
||||||
String maxAlignString = absoluteMaxAlignComponent.getText().toLowerCase();
|
|
||||||
int absoluteMax =
|
|
||||||
("none".equals(maxAlignString)) ? 0 : Integer.decode(maxAlignString).intValue();
|
|
||||||
dataOrganization.setAbsoluteMaxAlignment(absoluteMax);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedMachineAlignment() {
|
|
||||||
int machineAlignment = Integer.decode(machineAlignComponent.getText()).intValue();
|
|
||||||
dataOrganization.setMachineAlignment(machineAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedDefaultAlignment() {
|
|
||||||
int defaultAlignment = Integer.decode(defaultAlignComponent.getText()).intValue();
|
|
||||||
dataOrganization.setDefaultAlignment(defaultAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatedDefaultPointerAlignment() {
|
|
||||||
int defaultPointerAlignment = Integer.decode(pointerAlignComponent.getText()).intValue();
|
|
||||||
dataOrganization.setDefaultPointerAlignment(defaultPointerAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-156
@@ -1,156 +0,0 @@
|
|||||||
/* ###
|
|
||||||
* IP: GHIDRA
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
package ghidra.app.plugin.core.datamgr;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.event.TableModelListener;
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
|
|
||||||
import ghidra.program.model.data.DataOrganizationImpl;
|
|
||||||
import ghidra.util.Msg;
|
|
||||||
import ghidra.util.exception.NoValueException;
|
|
||||||
import ghidra.util.table.GhidraTable;
|
|
||||||
|
|
||||||
public class SizeAlignmentPanel extends JPanel {
|
|
||||||
|
|
||||||
GhidraTable table;
|
|
||||||
DataOrganizationImpl dataOrganization;
|
|
||||||
|
|
||||||
public SizeAlignmentPanel() {
|
|
||||||
super(new BorderLayout());
|
|
||||||
TableModel tableModel = new SizeAlignmentTableModel();
|
|
||||||
table = new GhidraTable(tableModel);
|
|
||||||
table.setAutoEditEnabled(true);
|
|
||||||
JScrollPane sp = new JScrollPane(table);
|
|
||||||
table.setPreferredScrollableViewportSize(new Dimension(200, 80));
|
|
||||||
add(sp, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrganization(DataOrganizationImpl dataOrganization) {
|
|
||||||
this.dataOrganization = dataOrganization;
|
|
||||||
((SizeAlignmentTableModel) table.getModel()).fireTableDataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
class SizeAlignmentTableModel extends AbstractTableModel {
|
|
||||||
|
|
||||||
private final String[] columnNames = new String[] { "Size", "Alignment" };
|
|
||||||
private final int SIZE_COLUMN = 0;
|
|
||||||
private final int ALIGNMENT_COLUMN = 1;
|
|
||||||
|
|
||||||
SizeAlignmentTableModel() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTableModelListener(TableModelListener l) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
|
||||||
return Integer.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return columnNames.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int columnIndex) {
|
|
||||||
return columnNames[columnIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
return dataOrganization.getSizeAlignmentCount() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
|
||||||
int[] sizes = dataOrganization.getSizes();
|
|
||||||
if (rowIndex < sizes.length) {
|
|
||||||
int size = sizes[rowIndex];
|
|
||||||
if (columnIndex == SIZE_COLUMN) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
else if (columnIndex == ALIGNMENT_COLUMN) {
|
|
||||||
try {
|
|
||||||
return dataOrganization.getSizeAlignment(size);
|
|
||||||
}
|
|
||||||
catch (NoValueException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
|
||||||
if (rowIndex == dataOrganization.getSizeAlignmentCount()) {
|
|
||||||
return columnIndex == SIZE_COLUMN;
|
|
||||||
}
|
|
||||||
return columnIndex == ALIGNMENT_COLUMN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeTableModelListener(TableModelListener l) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValueAt(Object value, int rowIndex, int columnIndex) {
|
|
||||||
if (value == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int[] sizes = dataOrganization.getSizes();
|
|
||||||
if (rowIndex < sizes.length) {
|
|
||||||
int alignment = ((Integer) value).intValue();
|
|
||||||
int size = sizes[rowIndex];
|
|
||||||
dataOrganization.setSizeAlignment(size, alignment);
|
|
||||||
}
|
|
||||||
if (rowIndex == sizes.length) {
|
|
||||||
int size = ((Integer) value).intValue();
|
|
||||||
// Check that we don't already have this size.
|
|
||||||
try {
|
|
||||||
dataOrganization.getSizeAlignment(size);
|
|
||||||
setStatusMessage("An alignment is already defined for a size of " + size + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (NoValueException e) {
|
|
||||||
// Actually don't want to find a value so we can set one below.
|
|
||||||
}
|
|
||||||
int alignment = size; // Set the alignment to match the size initially.
|
|
||||||
dataOrganization.setSizeAlignment(size, alignment);
|
|
||||||
fireTableDataChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatusMessage(String message) {
|
|
||||||
// TODO Change this to write to the status line in the dialog.
|
|
||||||
Msg.showError(this, this, "Invalid Input", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+2
-1
@@ -41,7 +41,8 @@ class DataTypePreview implements Preview {
|
|||||||
public String getPreview(Memory memory, Address addr) {
|
public String getPreview(Memory memory, Address addr) {
|
||||||
try {
|
try {
|
||||||
MemBuffer mb = new DumbMemBufferImpl(memory, addr);
|
MemBuffer mb = new DumbMemBufferImpl(memory, addr);
|
||||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dt, mb, MAX_PREVIEW_LENGTH);
|
DataTypeInstance dti =
|
||||||
|
DataTypeInstance.getDataTypeInstance(dt, mb, MAX_PREVIEW_LENGTH, false);
|
||||||
if (dti == null) {
|
if (dti == null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public class ConvertToDoubleAction extends AbstractConvertAction {
|
|||||||
try {
|
try {
|
||||||
FloatFormat format =
|
FloatFormat format =
|
||||||
FloatFormatFactory.getFloatFormat(dataOrganization.getDoubleSize());
|
FloatFormatFactory.getFloatFormat(dataOrganization.getDoubleSize());
|
||||||
return format.round(format.getHostFloat(s.getBigInteger()));
|
return format.round(format.decodeBigFloat(s.getBigInteger()));
|
||||||
}
|
}
|
||||||
catch (UnsupportedFloatFormatException e) {
|
catch (UnsupportedFloatFormatException e) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ public class ConvertToFloatAction extends AbstractConvertAction {
|
|||||||
DataOrganization dataOrganization = program.getDataTypeManager().getDataOrganization();
|
DataOrganization dataOrganization = program.getDataTypeManager().getDataOrganization();
|
||||||
try {
|
try {
|
||||||
FloatFormat format = FloatFormatFactory.getFloatFormat(dataOrganization.getFloatSize());
|
FloatFormat format = FloatFormatFactory.getFloatFormat(dataOrganization.getFloatSize());
|
||||||
return format.round(format.getHostFloat(s.getBigInteger()));
|
return format.round(format.decodeBigFloat(s.getBigInteger()));
|
||||||
}
|
}
|
||||||
catch (UnsupportedFloatFormatException e) {
|
catch (UnsupportedFloatFormatException e) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+9
-6
@@ -100,16 +100,19 @@ class CreateArrayAction extends ListingContextAction {
|
|||||||
Variable var = varLoc.getVariable();
|
Variable var = varLoc.getVariable();
|
||||||
if (var.isStackVariable()) {
|
if (var.isStackVariable()) {
|
||||||
DataType dt = var.getDataType();
|
DataType dt = var.getDataType();
|
||||||
int len = var.getLength();
|
if (dt.getLength() < 1) {
|
||||||
int defaultElements = plugin.getMaxStackVariableSize(fun, var);
|
return;
|
||||||
if (defaultElements <= 0) {
|
|
||||||
defaultElements = 1;
|
|
||||||
}
|
}
|
||||||
int n = getNumElements(dt, Integer.MAX_VALUE, defaultElements);
|
int availableLen = plugin.getMaxStackVariableSize(fun, var);
|
||||||
|
if (availableLen <= 0) {
|
||||||
|
availableLen = 1;
|
||||||
|
}
|
||||||
|
int maxElements = availableLen / var.getDataType().getAlignedLength();
|
||||||
|
int n = getNumElements(dt, Integer.MAX_VALUE, maxElements);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Array array = new ArrayDataType(dt, n, len);
|
Array array = new ArrayDataType(dt, n, -1);
|
||||||
plugin.createData(array, context, true, true);
|
plugin.createData(array, context, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -22,6 +22,7 @@ import ghidra.app.util.cparser.C.ParseException;
|
|||||||
import ghidra.app.util.parser.FunctionSignatureParser;
|
import ghidra.app.util.parser.FunctionSignatureParser;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.AbstractFloatDataType;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
||||||
@@ -1206,6 +1207,7 @@ public class FunctionEditorModel {
|
|||||||
catch (InvalidInputException e) {
|
catch (InvalidInputException e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
setFunctionData(f);
|
setFunctionData(f);
|
||||||
isInParsingMode = false;
|
isInParsingMode = false;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -33,6 +33,7 @@ import ghidra.app.util.datatype.DataTypeSelectionEditor;
|
|||||||
import ghidra.app.util.datatype.NavigationDirection;
|
import ghidra.app.util.datatype.NavigationDirection;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.AbstractFloatDataType;
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.Register;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
|||||||
+5
-5
@@ -202,7 +202,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
|||||||
dt = element.getDataType();
|
dt = element.getDataType();
|
||||||
dtLen = dt.getLength();
|
dtLen = dt.getLength();
|
||||||
return DataTypeInstance.getDataTypeInstance(dt,
|
return DataTypeInstance.getDataTypeInstance(dt,
|
||||||
(dtLen > 0) ? dtLen : element.getLength());
|
(dtLen > 0) ? dtLen : element.getLength(), true);
|
||||||
case NAME:
|
case NAME:
|
||||||
String fieldName = getFieldNameAtRow(rowIndex, (StackFrameDataType) viewComposite);
|
String fieldName = getFieldNameAtRow(rowIndex, (StackFrameDataType) viewComposite);
|
||||||
if (fieldName == null) {
|
if (fieldName == null) {
|
||||||
@@ -1127,7 +1127,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
|||||||
OffsetPairs offsetSelection = getRelOffsetSelection();
|
OffsetPairs offsetSelection = getRelOffsetSelection();
|
||||||
int transID = startTransaction("Apply Data Type \"" + dt.getName() + "\"");
|
int transID = startTransaction("Apply Data Type \"" + dt.getName() + "\"");
|
||||||
try {
|
try {
|
||||||
fieldEdited(DataTypeInstance.getDataTypeInstance(dt, dtLength), index,
|
fieldEdited(DataTypeInstance.getDataTypeInstance(dt, dtLength, true), index,
|
||||||
getDataTypeColumn());
|
getDataTypeColumn());
|
||||||
setRelOffsetSelection(offsetSelection);
|
setRelOffsetSelection(offsetSelection);
|
||||||
}
|
}
|
||||||
@@ -1157,7 +1157,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
|||||||
if (max == Integer.MAX_VALUE) {
|
if (max == Integer.MAX_VALUE) {
|
||||||
return Integer.MAX_VALUE;
|
return Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
return max / dtc.getLength();
|
return max / dtc.getDataType().getAlignedLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1320,7 +1320,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
|||||||
dtName = dt.getDisplayName();
|
dtName = dt.getDisplayName();
|
||||||
if (dtString.equals(dtName)) {
|
if (dtString.equals(dtName)) {
|
||||||
return DataTypeInstance.getDataTypeInstance(element.getDataType(),
|
return DataTypeInstance.getDataTypeInstance(element.getDataType(),
|
||||||
element.getLength());
|
element.getLength(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1346,7 +1346,7 @@ public class StackEditorModel extends CompositeEditorModel {
|
|||||||
if (maxLength > 0 && newLength > maxLength) {
|
if (maxLength > 0 && newLength > maxLength) {
|
||||||
throw new UsrException(newDt.getDisplayName() + " doesn't fit.");
|
throw new UsrException(newDt.getDisplayName() + " doesn't fit.");
|
||||||
}
|
}
|
||||||
return DataTypeInstance.getDataTypeInstance(newDt, newLength);
|
return DataTypeInstance.getDataTypeInstance(newDt, newLength, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+6
-1
@@ -25,6 +25,7 @@ import ghidra.app.util.bin.format.dwarf4.encoding.*;
|
|||||||
import ghidra.app.util.bin.format.dwarf4.expression.DWARFExpressionException;
|
import ghidra.app.util.bin.format.dwarf4.expression.DWARFExpressionException;
|
||||||
import ghidra.app.util.bin.format.dwarf4.next.DWARFDataTypeImporter.DWARFDataType;
|
import ghidra.app.util.bin.format.dwarf4.next.DWARFDataTypeImporter.DWARFDataType;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.AbstractFloatDataType;
|
||||||
import ghidra.program.model.lang.CompilerSpec;
|
import ghidra.program.model.lang.CompilerSpec;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
@@ -381,7 +382,7 @@ public class DWARFDataTypeManager {
|
|||||||
String mangledName = null;
|
String mangledName = null;
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
dt = baseDataTypes.get(name);
|
dt = baseDataTypes.get(name);
|
||||||
if (dt != null && dt.getLength() == dwarfSize &&
|
if (dt != null && dt.getAlignedLength() == dwarfSize &&
|
||||||
isEncodingCompatible(dwarfEncoding, dt)) {
|
isEncodingCompatible(dwarfEncoding, dt)) {
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
@@ -394,6 +395,9 @@ public class DWARFDataTypeManager {
|
|||||||
dt = switch (dwarfEncoding) {
|
dt = switch (dwarfEncoding) {
|
||||||
case DWARFEncoding.DW_ATE_address -> baseDataTypeVoid; // TODO: Check if bytesize != 0 - may want to make a void pointer
|
case DWARFEncoding.DW_ATE_address -> baseDataTypeVoid; // TODO: Check if bytesize != 0 - may want to make a void pointer
|
||||||
case DWARFEncoding.DW_ATE_boolean -> dwarfSize == 1 ? baseDataTypeBool : null;
|
case DWARFEncoding.DW_ATE_boolean -> dwarfSize == 1 ? baseDataTypeBool : null;
|
||||||
|
// TODO: Float lookup by length must use "raw" encoding size since "aligned" lengths
|
||||||
|
// may be duplicated across different float types. Lookup by name is preferred.
|
||||||
|
// May need to add name lookup capability to AbstractFloatDataType
|
||||||
case DWARFEncoding.DW_ATE_float -> AbstractFloatDataType.getFloatDataType(dwarfSize,
|
case DWARFEncoding.DW_ATE_float -> AbstractFloatDataType.getFloatDataType(dwarfSize,
|
||||||
getCorrectDTMForFixedLengthTypes(name, dwarfSize));
|
getCorrectDTMForFixedLengthTypes(name, dwarfSize));
|
||||||
case DWARFEncoding.DW_ATE_signed -> AbstractIntegerDataType.getSignedDataType(dwarfSize,
|
case DWARFEncoding.DW_ATE_signed -> AbstractIntegerDataType.getSignedDataType(dwarfSize,
|
||||||
@@ -426,6 +430,7 @@ public class DWARFDataTypeManager {
|
|||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private DataTypeManager getCorrectDTMForFixedLengthTypes(String name, int dwarfSize) {
|
private DataTypeManager getCorrectDTMForFixedLengthTypes(String name, int dwarfSize) {
|
||||||
// If the requested name of the base type appears to have a bitsize string
|
// If the requested name of the base type appears to have a bitsize string
|
||||||
// embedded in it, this chunk of code will switch between using the normal DTM
|
// embedded in it, this chunk of code will switch between using the normal DTM
|
||||||
|
|||||||
+4
-2
@@ -25,6 +25,8 @@ import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
|
|||||||
import ghidra.app.util.bin.format.pe.cli.tables.*;
|
import ghidra.app.util.bin.format.pe.cli.tables.*;
|
||||||
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexTypeDefOrRef;
|
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexTypeDefOrRef;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.Float32DataType;
|
||||||
|
import ghidra.program.model.data.floats.Float64DataType;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
import ghidra.util.exception.InvalidInputException;
|
||||||
|
|
||||||
public abstract class CliAbstractSig extends CliBlob implements CliRepresentable {
|
public abstract class CliAbstractSig extends CliBlob implements CliRepresentable {
|
||||||
@@ -139,9 +141,9 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
|||||||
return UnsignedIntegerDataType.dataType;
|
return UnsignedIntegerDataType.dataType;
|
||||||
|
|
||||||
case ELEMENT_TYPE_R4:
|
case ELEMENT_TYPE_R4:
|
||||||
return Float4DataType.dataType;
|
return Float32DataType.dataType;
|
||||||
case ELEMENT_TYPE_R8:
|
case ELEMENT_TYPE_R8:
|
||||||
return Float8DataType.dataType;
|
return Float64DataType.dataType;
|
||||||
|
|
||||||
case ELEMENT_TYPE_I8:
|
case ELEMENT_TYPE_I8:
|
||||||
return LongLongDataType.dataType;
|
return LongLongDataType.dataType;
|
||||||
|
|||||||
+4
-2
@@ -32,6 +32,8 @@ import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodDef.CliMethodDefRo
|
|||||||
import ghidra.app.util.bin.format.pe.cli.tables.CliTypeTable;
|
import ghidra.app.util.bin.format.pe.cli.tables.CliTypeTable;
|
||||||
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexCustomAttributeType;
|
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexCustomAttributeType;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.Float32DataType;
|
||||||
|
import ghidra.program.model.data.floats.Float64DataType;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
import ghidra.util.exception.InvalidInputException;
|
||||||
|
|
||||||
@@ -410,12 +412,12 @@ public class CliBlobCustomAttrib extends CliBlob {
|
|||||||
|
|
||||||
case ELEMENT_TYPE_R4:
|
case ELEMENT_TYPE_R4:
|
||||||
addFixedArg(processFixedArgs, baseTypeCode,
|
addFixedArg(processFixedArgs, baseTypeCode,
|
||||||
reader.readNextByteArray(Float4DataType.dataType.getLength()));
|
reader.readNextByteArray(Float32DataType.dataType.getLength()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELEMENT_TYPE_R8:
|
case ELEMENT_TYPE_R8:
|
||||||
addFixedArg(processFixedArgs, baseTypeCode,
|
addFixedArg(processFixedArgs, baseTypeCode,
|
||||||
reader.readNextByteArray(Float8DataType.dataType.getLength()));
|
reader.readNextByteArray(Float64DataType.dataType.getLength()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELEMENT_TYPE_STRING:
|
case ELEMENT_TYPE_STRING:
|
||||||
|
|||||||
+4
-4
@@ -15,8 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.datatype.microsoft;
|
package ghidra.app.util.datatype.microsoft;
|
||||||
|
|
||||||
import static ghidra.app.util.datatype.microsoft.MSDataTypeUtils.getAbsoluteAddress;
|
import static ghidra.app.util.datatype.microsoft.MSDataTypeUtils.*;
|
||||||
import static ghidra.app.util.datatype.microsoft.MSDataTypeUtils.is64Bit;
|
|
||||||
|
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.docking.settings.SettingsImpl;
|
import ghidra.docking.settings.SettingsImpl;
|
||||||
@@ -111,7 +110,7 @@ public class RTTI0DataType extends RTTIDataType {
|
|||||||
Address nameAddress = start.add(nameOffset);
|
Address nameAddress = start.add(nameOffset);
|
||||||
MemoryBufferImpl nameBuf = new MemoryBufferImpl(buf.getMemory(), nameAddress, 1024);
|
MemoryBufferImpl nameBuf = new MemoryBufferImpl(buf.getMemory(), nameAddress, 1024);
|
||||||
DataTypeInstance dti =
|
DataTypeInstance dti =
|
||||||
DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf);
|
DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf, false);
|
||||||
|
|
||||||
if (dti != null) {
|
if (dti != null) {
|
||||||
comps[2] = new ReadOnlyDataTypeComponent(dti.getDataType(), this, dti.getLength(), 2,
|
comps[2] = new ReadOnlyDataTypeComponent(dti.getDataType(), this, dti.getLength(), 2,
|
||||||
@@ -178,7 +177,8 @@ public class RTTI0DataType extends RTTIDataType {
|
|||||||
WrappedMemBuffer nameBuf = null;
|
WrappedMemBuffer nameBuf = null;
|
||||||
try {
|
try {
|
||||||
nameBuf = new WrappedMemBuffer(buf, getNameOffset(buf.getMemory().getProgram()));
|
nameBuf = new WrappedMemBuffer(buf, getNameOffset(buf.getMemory().getProgram()));
|
||||||
dti = DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf);
|
dti = DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
catch (AddressOutOfBoundsException e) {
|
catch (AddressOutOfBoundsException e) {
|
||||||
// ignore
|
// ignore
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import ghidra.program.database.data.DataTypeUtilities;
|
import ghidra.program.database.data.DataTypeUtilities;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.data.Enum;
|
import ghidra.program.model.data.Enum;
|
||||||
|
import ghidra.program.model.data.floats.Float128DataType;
|
||||||
import ghidra.program.model.symbol.Namespace;
|
import ghidra.program.model.symbol.Namespace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,7 +284,7 @@ public class DemangledDataType extends DemangledType {
|
|||||||
dt = FloatDataType.dataType;
|
dt = FloatDataType.dataType;
|
||||||
}
|
}
|
||||||
else if (FLOAT128.equals(name)) {
|
else if (FLOAT128.equals(name)) {
|
||||||
dt = new TypedefDataType(FLOAT128, Float16DataType.dataType);
|
dt = new TypedefDataType(FLOAT128, Float128DataType.dataType);
|
||||||
}
|
}
|
||||||
else if (DOUBLE.equals(name)) {
|
else if (DOUBLE.equals(name)) {
|
||||||
dt = DoubleDataType.dataType;
|
dt = DoubleDataType.dataType;
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class DefinedDataXmlMgr {
|
|||||||
|
|
||||||
private void clearExistingData(Address addr, int size, DataType dt, Listing listing) {
|
private void clearExistingData(Address addr, int size, DataType dt, Listing listing) {
|
||||||
DumbMemBufferImpl buf = new DumbMemBufferImpl(program.getMemory(), addr);
|
DumbMemBufferImpl buf = new DumbMemBufferImpl(program.getMemory(), addr);
|
||||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dt, buf, size);
|
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dt, buf, size, false);
|
||||||
if (dti != null) {
|
if (dti != null) {
|
||||||
boolean doClear = false;
|
boolean doClear = false;
|
||||||
Address maxAddr = addr.add(dti.getLength() - 1);
|
Address maxAddr = addr.add(dti.getLength() - 1);
|
||||||
|
|||||||
+2
-2
@@ -784,7 +784,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||||||
false)
|
false)
|
||||||
: LittleEndianDataConverter.INSTANCE.getBigInteger(bytes, index, elementSize,
|
: LittleEndianDataConverter.INSTANCE.getBigInteger(bytes, index, elementSize,
|
||||||
false);
|
false);
|
||||||
BigDecimal val = ff.round(ff.getHostFloat(encoding));
|
BigDecimal val = ff.round(ff.decodeBigFloat(encoding));
|
||||||
return val.toString();
|
return val.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -879,7 +879,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||||||
if (reg != null && floatRegSet.contains(reg)) {
|
if (reg != null && floatRegSet.contains(reg)) {
|
||||||
FloatFormat floatFormat = FloatFormatFactory.getFloatFormat(size);
|
FloatFormat floatFormat = FloatFormatFactory.getFloatFormat(size);
|
||||||
BigDecimal hostFloat =
|
BigDecimal hostFloat =
|
||||||
floatFormat.round(floatFormat.getHostFloat(new BigInteger(1, values)));
|
floatFormat.round(floatFormat.decodeBigFloat(new BigInteger(1, values)));
|
||||||
floatStr = " (" + hostFloat.toString() + ")";
|
floatStr = " (" + hostFloat.toString() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-13
@@ -22,7 +22,6 @@ import static org.junit.Assert.*;
|
|||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import ghidra.app.events.ProgramActivatedPluginEvent;
|
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||||
import ghidra.app.plugin.core.datapreview.DataTypePreviewPlugin.DTPPTableModel;
|
import ghidra.app.plugin.core.datapreview.DataTypePreviewPlugin.DTPPTableModel;
|
||||||
@@ -174,6 +173,7 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
// integerSize = 4;
|
// integerSize = 4;
|
||||||
// longSize = 4;
|
// longSize = 4;
|
||||||
// defaultAlignment = 1;
|
// defaultAlignment = 1;
|
||||||
|
// alignment per size: 2->2, 4->4, 8->4
|
||||||
|
|
||||||
plugin.addDataType(IntegerDataType.dataType);
|
plugin.addDataType(IntegerDataType.dataType);
|
||||||
plugin.addDataType(LongDataType.dataType);
|
plugin.addDataType(LongDataType.dataType);
|
||||||
@@ -190,12 +190,11 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
assertEquals(6, model.getRowCount());
|
assertEquals(6, model.getRowCount());
|
||||||
|
|
||||||
Program program = buildProgram();
|
Program program = buildProgram();
|
||||||
|
|
||||||
DataOrganizationImpl dataOrganization =
|
DataOrganizationImpl dataOrganization =
|
||||||
(DataOrganizationImpl) program.getDataTypeManager().getDataOrganization();
|
(DataOrganizationImpl) program.getCompilerSpec().getDataOrganization();
|
||||||
|
|
||||||
dataOrganization.setLongSize(8);
|
dataOrganization.setLongSize(8);
|
||||||
|
|
||||||
|
// Open program in tool and goto tested memory location
|
||||||
env.open(program);
|
env.open(program);
|
||||||
|
|
||||||
gotoService.goTo(addr(program, 0x100df26));
|
gotoService.goTo(addr(program, 0x100df26));
|
||||||
@@ -210,19 +209,23 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
assertEquals("61004D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 8-byte long at offset 4
|
assertEquals("61004D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 8-byte long at offset 4
|
||||||
assertEquals("72h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 12
|
assertEquals("72h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 2-byte short at offset 12
|
||||||
|
|
||||||
// deactivate program
|
env.close(program);
|
||||||
plugin.getTool().firePluginEvent(new ProgramActivatedPluginEvent("Test", null));
|
|
||||||
waitForPostedSwingRunnables();
|
|
||||||
|
|
||||||
|
// Re-create program with mutated data-organization to simulate shift to 3-byte aligned types
|
||||||
// NOTE: Altering data organization on-the-fly is not supported
|
// NOTE: Altering data organization on-the-fly is not supported
|
||||||
dataOrganization.setDefaultAlignment(2);
|
|
||||||
|
// alignment map should jive with 3-byte mutliple primitive type sizes
|
||||||
|
dataOrganization.clearSizeAlignmentMap();
|
||||||
|
dataOrganization.setSizeAlignment(1, 1);
|
||||||
|
dataOrganization.setSizeAlignment(3, 3);
|
||||||
|
dataOrganization.setSizeAlignment(6, 6);
|
||||||
dataOrganization.setShortSize(3);
|
dataOrganization.setShortSize(3);
|
||||||
dataOrganization.setIntegerSize(3);
|
dataOrganization.setIntegerSize(3);
|
||||||
dataOrganization.setLongSize(6);
|
dataOrganization.setLongSize(6);
|
||||||
|
|
||||||
// activate program
|
// Open program in tool and goto tested memory location
|
||||||
plugin.getTool().firePluginEvent(new ProgramActivatedPluginEvent("Test", program));
|
program = buildProgram();
|
||||||
waitForPostedSwingRunnables();
|
env.open(program);
|
||||||
|
|
||||||
gotoService.goTo(addr(program, 0x100df26));
|
gotoService.goTo(addr(program, 0x100df26));
|
||||||
|
|
||||||
@@ -231,8 +234,8 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
assertEquals("680054h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 3-byte short
|
assertEquals("680054h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 3-byte short
|
||||||
|
|
||||||
assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 3-byte int at offset 0
|
assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 3-byte int at offset 0
|
||||||
assertEquals("4D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 6-byte long at offset 4
|
assertEquals("61004D0020h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 6-byte long at offset 6
|
||||||
assertEquals("720061h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 3-byte short at offset 10
|
assertEquals("670072h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 3-byte short at offset 12
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -863,7 +863,7 @@ public class EquatePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
|||||||
}
|
}
|
||||||
else if (name.indexOf("Float") >= 0) {
|
else if (name.indexOf("Float") >= 0) {
|
||||||
assertTrue(popupPath[1].startsWith("Float"));
|
assertTrue(popupPath[1].startsWith("Float"));
|
||||||
assertTrue(popupPath[1].endsWith(" 5.605194E-45"));
|
assertTrue(popupPath[1].endsWith(" 5.6051939E-45"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fail("Unhandled Convert item: " + name);
|
fail("Unhandled Convert item: " + name);
|
||||||
|
|||||||
+3
-2
@@ -23,6 +23,7 @@ import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
|||||||
import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin;
|
import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin;
|
||||||
import ghidra.app.plugin.core.script.GhidraScriptMgrPlugin;
|
import ghidra.app.plugin.core.script.GhidraScriptMgrPlugin;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
import ghidra.pcode.floatformat.BigFloat;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSet;
|
import ghidra.program.model.address.AddressSet;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
@@ -400,13 +401,13 @@ public class GhidraScriptRealProgramTest extends AbstractGhidraHeadedIntegration
|
|||||||
address = script.toAddr(0x010085a7);
|
address = script.toAddr(0x010085a7);
|
||||||
data = script.createFloat(address);
|
data = script.createFloat(address);
|
||||||
assertNotNull(data);
|
assertNotNull(data);
|
||||||
assertEquals(-1.4682312f, data.getValue());
|
assertEquals("-1.468231", ((BigFloat) data.getValue()).toString());
|
||||||
script.clearListing(address);
|
script.clearListing(address);
|
||||||
|
|
||||||
address = script.toAddr(0x010085a9);
|
address = script.toAddr(0x010085a9);
|
||||||
data = script.createDouble(address);
|
data = script.createDouble(address);
|
||||||
assertNotNull(data);
|
assertNotNull(data);
|
||||||
assertEquals(-8.373196719664668E298, data.getValue());
|
assertEquals("-8.37319671966467E+298", ((BigFloat) data.getValue()).toString());
|
||||||
script.clearListing(address);
|
script.clearListing(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -64,7 +64,7 @@ public class ConvertDoubleAction extends ConvertConstantAction {
|
|||||||
private static BigDecimal value(int size, Scalar s) {
|
private static BigDecimal value(int size, Scalar s) {
|
||||||
try {
|
try {
|
||||||
FloatFormat format = FloatFormatFactory.getFloatFormat(size);
|
FloatFormat format = FloatFormatFactory.getFloatFormat(size);
|
||||||
return format.round(format.getHostFloat(s.getBigInteger()));
|
return format.round(format.decodeBigFloat(s.getBigInteger()));
|
||||||
}
|
}
|
||||||
catch (UnsupportedFloatFormatException e) {
|
catch (UnsupportedFloatFormatException e) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+1
-1
@@ -64,7 +64,7 @@ public class ConvertFloatAction extends ConvertConstantAction {
|
|||||||
private static BigDecimal value(int size, Scalar s) {
|
private static BigDecimal value(int size, Scalar s) {
|
||||||
try {
|
try {
|
||||||
FloatFormat format = FloatFormatFactory.getFloatFormat(size);
|
FloatFormat format = FloatFormatFactory.getFloatFormat(size);
|
||||||
return format.round(format.getHostFloat(s.getBigInteger()));
|
return format.round(format.decodeBigFloat(s.getBigInteger()));
|
||||||
}
|
}
|
||||||
catch (UnsupportedFloatFormatException e) {
|
catch (UnsupportedFloatFormatException e) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -794,7 +794,7 @@ public class PdbParser {
|
|||||||
|
|
||||||
void createData(Address address, DataType dataType, MessageLog log) {
|
void createData(Address address, DataType dataType, MessageLog log) {
|
||||||
DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(program.getMemory(), address);
|
DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(program.getMemory(), address);
|
||||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer);
|
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer, false);
|
||||||
if (dti == null) {
|
if (dti == null) {
|
||||||
log.appendMsg("PDB",
|
log.appendMsg("PDB",
|
||||||
"Failed to apply datatype " + dataType.getName() + " at " + address);
|
"Failed to apply datatype " + dataType.getName() + " at " + address);
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ public class DataSymbolApplier extends MsSymbolApplier {
|
|||||||
//TODO: might want to do an ApplyDatatypeCmd here!!!
|
//TODO: might want to do an ApplyDatatypeCmd here!!!
|
||||||
DumbMemBufferImpl memBuffer =
|
DumbMemBufferImpl memBuffer =
|
||||||
new DumbMemBufferImpl(applicator.getProgram().getMemory(), address);
|
new DumbMemBufferImpl(applicator.getProgram().getMemory(), address);
|
||||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer);
|
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer, false);
|
||||||
if (dti == null) {
|
if (dti == null) {
|
||||||
applicator.appendLogMsg(
|
applicator.appendLogMsg(
|
||||||
"Error: Failed to apply datatype " + dataType.getName() + " at " + address);
|
"Error: Failed to apply datatype " + dataType.getName() + " at " + address);
|
||||||
|
|||||||
+9
-5
@@ -20,6 +20,7 @@ import java.util.*;
|
|||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.PrimitiveMsType;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.type.PrimitiveMsType;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.data.floats.AbstractFloatDataType;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -516,21 +517,24 @@ public class PdbPrimitiveTypeApplicator {
|
|||||||
return getRealType(16, "float128");
|
return getRealType(16, "float128");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* First get type from "other" list, which are typedefs to underlying primitives. If it does
|
* First get type from "other" list, which are typedefs to underlying primitives. If it does
|
||||||
* not exist, then find the proper underlying primitive, create the typedef, and cache this
|
* not exist, then find the proper underlying primitive, create the typedef, and cache this
|
||||||
* newly minted (typedef) unique primitive type.
|
* newly minted (typedef) unique primitive type.
|
||||||
|
* @param rawSize "raw" encoding size in bytes
|
||||||
|
* @param name assigned type name
|
||||||
*/
|
*/
|
||||||
private DataType getRealType(int size, String name) {
|
private DataType getRealType(int rawSize, String name) {
|
||||||
DataType dataType = otherPrimitives.get(name);
|
DataType dataType = otherPrimitives.get(name);
|
||||||
if (dataType != null) {
|
if (dataType != null) {
|
||||||
return dataType;
|
return dataType;
|
||||||
}
|
}
|
||||||
dataType = floatGhidraPrimitives.get(size);
|
dataType = floatGhidraPrimitives.get(rawSize);
|
||||||
DataType resolved;
|
DataType resolved;
|
||||||
if (dataType == null) {
|
if (dataType == null) {
|
||||||
resolved = resolve(AbstractFloatDataType.getFloatDataType(size, getDataTypeManager()));
|
resolved =
|
||||||
floatGhidraPrimitives.put(size, resolved);
|
resolve(AbstractFloatDataType.getFloatDataType(rawSize, getDataTypeManager()));
|
||||||
|
floatGhidraPrimitives.put(rawSize, resolved);
|
||||||
if (resolved instanceof Undefined) { // Not a real type implemented in Ghidra.
|
if (resolved instanceof Undefined) { // Not a real type implemented in Ghidra.
|
||||||
DataType type = createTypedef(name, resolved);
|
DataType type = createTypedef(name, resolved);
|
||||||
resolved = resolve(type);
|
resolved = resolve(type);
|
||||||
|
|||||||
+10
-10
@@ -38,23 +38,23 @@ public class OpBehaviorFloatAbsTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long a = ff.getEncoding(2.5);
|
long a = ff.getEncoding(2.5);
|
||||||
long result = op.evaluateUnary(8, 8, ff.opAbs(a));
|
long result = op.evaluateUnary(8, 8, ff.opAbs(a));
|
||||||
Assert.assertEquals(2.5, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.5);
|
a = ff.getEncoding(-2.5);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(2.5, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -66,23 +66,23 @@ public class OpBehaviorFloatAbsTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
||||||
BigInteger result = op.evaluateUnary(8, 8, a);
|
BigInteger result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(false);
|
a = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-14
@@ -39,32 +39,32 @@ public class OpBehaviorFloatAddTest extends AbstractOpBehaviorTest {
|
|||||||
long a = ff.getEncoding(1.234);
|
long a = ff.getEncoding(1.234);
|
||||||
long b = ff.getEncoding(1.123);
|
long b = ff.getEncoding(1.123);
|
||||||
long result = op.evaluateBinary(8, 8, a, b);// 1.234 + 1.123
|
long result = op.evaluateBinary(8, 8, a, b);// 1.234 + 1.123
|
||||||
Assert.assertEquals(2.357, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.357, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-1.123);
|
a = ff.getEncoding(-1.123);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -1.123 + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// -1.123 + 1.123
|
||||||
Assert.assertEquals(0d, ff.getHostFloat(result), 0);
|
Assert.assertEquals(0d, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// +INFINITY + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// +INFINITY + 1.123
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + 1.123
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
b = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + -INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + -INFINITY
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.POSITIVE_INFINITY);
|
b = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + +INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + +INFINITY
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
b = ff.getEncoding(1.123);
|
b = ff.getEncoding(1.123);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// NaN + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// NaN + 1.123
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -77,32 +77,32 @@ public class OpBehaviorFloatAddTest extends AbstractOpBehaviorTest {
|
|||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(1.234d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(1.234d));
|
||||||
BigInteger b = ff.getEncoding(ff.getBigFloat(1.123d));
|
BigInteger b = ff.getEncoding(ff.getBigFloat(1.123d));
|
||||||
BigInteger result = op.evaluateBinary(8, 8, a, b);// 1.234 + 1.123
|
BigInteger result = op.evaluateBinary(8, 8, a, b);// 1.234 + 1.123
|
||||||
Assert.assertEquals(ff.getBigFloat(2.357), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.357), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-1.123d));
|
a = ff.getEncoding(ff.getBigFloat(-1.123d));
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -1.123 + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// -1.123 + 1.123
|
||||||
Assert.assertEquals(ff.getBigZero(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigZero(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigInfinity(false));
|
a = ff.getEncoding(ff.getBigInfinity(false));
|
||||||
result = op.evaluateBinary(8, 8, a, b);// +INFINITY + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// +INFINITY + 1.123
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + 1.123
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigInfinityEncoding(true);
|
b = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + -INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + -INFINITY
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getEncoding(ff.getBigInfinity(false));
|
b = ff.getEncoding(ff.getBigInfinity(false));
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + +INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY + +INFINITY
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
b = ff.getEncoding(ff.getBigFloat(1.123d));
|
b = ff.getEncoding(ff.getBigFloat(1.123d));
|
||||||
result = op.evaluateBinary(8, 8, a, b);// NaN + 1.123
|
result = op.evaluateBinary(8, 8, a, b);// NaN + 1.123
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -38,23 +38,23 @@ public class OpBehaviorFloatCeilTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long a = ff.getEncoding(2.5);
|
long a = ff.getEncoding(2.5);
|
||||||
long result = ff.opCeil(a);
|
long result = ff.opCeil(a);
|
||||||
Assert.assertEquals(3.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(3.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.5);
|
a = ff.getEncoding(-2.5);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-2.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -66,23 +66,23 @@ public class OpBehaviorFloatCeilTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
||||||
BigInteger result = op.evaluateUnary(8, 8, a);
|
BigInteger result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(3.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(3.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(false);
|
a = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -39,19 +39,19 @@ public class OpBehaviorFloatDivTest extends AbstractOpBehaviorTest {
|
|||||||
long a = ff.getEncoding(3.75);
|
long a = ff.getEncoding(3.75);
|
||||||
long b = ff.getEncoding(1.5);
|
long b = ff.getEncoding(1.5);
|
||||||
long result = ff.opDiv(a, b);
|
long result = ff.opDiv(a, b);
|
||||||
Assert.assertEquals(2.5, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(0);
|
b = ff.getEncoding(0);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-3.75);
|
a = ff.getEncoding(-3.75);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.NaN);
|
b = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -64,19 +64,19 @@ public class OpBehaviorFloatDivTest extends AbstractOpBehaviorTest {
|
|||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(3.75d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(3.75d));
|
||||||
BigInteger b = ff.getEncoding(ff.getBigFloat(1.5d));
|
BigInteger b = ff.getEncoding(ff.getBigFloat(1.5d));
|
||||||
BigInteger result = op.evaluateBinary(8, 8, a, b);
|
BigInteger result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigZeroEncoding(false);
|
b = ff.getBigZeroEncoding(false);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-3.75d));
|
a = ff.getEncoding(ff.getBigFloat(-3.75d));
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigNaNEncoding(false);
|
b = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -39,23 +39,23 @@ public class OpBehaviorFloatFloat2FloatTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long a = ff4.getEncoding(1.75);
|
long a = ff4.getEncoding(1.75);
|
||||||
long result = op.evaluateUnary(8, 4, a);
|
long result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(1.75, ff8.getHostFloat(result), 0);
|
Assert.assertEquals(1.75, ff8.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff4.getEncoding(-1.75);
|
a = ff4.getEncoding(-1.75);
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(-1.75, ff8.getHostFloat(result), 0);
|
Assert.assertEquals(-1.75, ff8.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff4.getEncoding(Float.POSITIVE_INFINITY);
|
a = ff4.getEncoding(Float.POSITIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff8.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff8.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff4.getEncoding(Float.NEGATIVE_INFINITY);
|
a = ff4.getEncoding(Float.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff8.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff8.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff4.getEncoding(Float.NaN);
|
a = ff4.getEncoding(Float.NaN);
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(Double.NaN, ff8.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff8.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -68,23 +68,23 @@ public class OpBehaviorFloatFloat2FloatTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger a = ff4.getEncoding(ff4.getBigFloat(1.75d));
|
BigInteger a = ff4.getEncoding(ff4.getBigFloat(1.75d));
|
||||||
BigInteger result = op.evaluateUnary(8, 4, a);
|
BigInteger result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(ff8.getBigFloat(1.75d), ff8.getHostFloat(result));
|
Assert.assertEquals(ff8.getBigFloat(1.75d), ff8.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff4.getEncoding(ff4.getBigFloat(-1.75d));
|
a = ff4.getEncoding(ff4.getBigFloat(-1.75d));
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(ff8.getBigFloat(-1.75d), ff8.getHostFloat(result));
|
Assert.assertEquals(ff8.getBigFloat(-1.75d), ff8.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff4.getEncoding(ff4.getBigInfinity(false));
|
a = ff4.getEncoding(ff4.getBigInfinity(false));
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(ff8.getBigInfinity(false), ff8.getHostFloat(result));
|
Assert.assertEquals(ff8.getBigInfinity(false), ff8.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff4.getEncoding(ff4.getBigInfinity(true));
|
a = ff4.getEncoding(ff4.getBigInfinity(true));
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(ff8.getBigInfinity(true), ff8.getHostFloat(result));
|
Assert.assertEquals(ff8.getBigInfinity(true), ff8.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff4.getEncoding(ff4.getBigNaN(false));
|
a = ff4.getEncoding(ff4.getBigNaN(false));
|
||||||
result = op.evaluateUnary(8, 4, a);
|
result = op.evaluateUnary(8, 4, a);
|
||||||
Assert.assertEquals(ff8.getBigNaN(false), ff8.getHostFloat(result));
|
Assert.assertEquals(ff8.getBigNaN(false), ff8.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -38,27 +38,27 @@ public class OpBehaviorFloatFloorTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long a = ff.getEncoding(2.5);
|
long a = ff.getEncoding(2.5);
|
||||||
long result = op.evaluateUnary(8, 8, a);
|
long result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(2.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.0);
|
a = ff.getEncoding(-2.0);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-2.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.5);
|
a = ff.getEncoding(-2.5);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-3.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-3.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -70,27 +70,27 @@ public class OpBehaviorFloatFloorTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
||||||
BigInteger result = op.evaluateUnary(8, 8, a);
|
BigInteger result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.0d));
|
a = ff.getEncoding(ff.getBigFloat(-2.0d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-3.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-3.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(false);
|
a = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -41,19 +41,19 @@ public class OpBehaviorFloatInt2FloatTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long result = op.evaluateUnary(4, 4, 2);
|
long result = op.evaluateUnary(4, 4, 2);
|
||||||
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(2.0d, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.0d, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
result = op.evaluateUnary(4, 4, -2);
|
result = op.evaluateUnary(4, 4, -2);
|
||||||
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(-2.0d, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.0d, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
result = op.evaluateUnary(4, 4, 0);
|
result = op.evaluateUnary(4, 4, 0);
|
||||||
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(0d, ff.getHostFloat(result), 0);
|
Assert.assertEquals(0d, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
result = op.evaluateUnary(4, 4, 0x0ffffffffL);
|
result = op.evaluateUnary(4, 4, 0x0ffffffffL);
|
||||||
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(-1.0d, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-1.0d, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -67,20 +67,20 @@ public class OpBehaviorFloatInt2FloatTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger result = op.evaluateUnary(4, 4, BigInteger.valueOf(2));
|
BigInteger result = op.evaluateUnary(4, 4, BigInteger.valueOf(2));
|
||||||
assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used
|
assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(ff.getBigFloat(2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
result = op.evaluateUnary(4, 4, BigInteger.valueOf(-2));
|
result = op.evaluateUnary(4, 4, BigInteger.valueOf(-2));
|
||||||
assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used
|
assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
result = op.evaluateUnary(4, 4, BigInteger.ZERO);
|
result = op.evaluateUnary(4, 4, BigInteger.ZERO);
|
||||||
assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used
|
assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used
|
||||||
Assert.assertEquals(ff.getBigZero(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigZero(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
BigInteger NEG_ONE = Utils.bytesToBigInteger(
|
BigInteger NEG_ONE = Utils.bytesToBigInteger(
|
||||||
new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }, 4, false, false);
|
new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }, 4, false, false);
|
||||||
result = op.evaluateUnary(4, 4, NEG_ONE);
|
result = op.evaluateUnary(4, 4, NEG_ONE);
|
||||||
Assert.assertEquals(ff.getBigFloat(-1.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-1.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -39,19 +39,19 @@ public class OpBehaviorFloatMultTest extends AbstractOpBehaviorTest {
|
|||||||
long a = ff.getEncoding(2.5);
|
long a = ff.getEncoding(2.5);
|
||||||
long b = ff.getEncoding(1.5);
|
long b = ff.getEncoding(1.5);
|
||||||
long result = op.evaluateBinary(8, 8, a, b);
|
long result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(3.75, ff.getHostFloat(result), 0);
|
Assert.assertEquals(3.75, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.POSITIVE_INFINITY);
|
b = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.NaN);
|
b = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -64,19 +64,19 @@ public class OpBehaviorFloatMultTest extends AbstractOpBehaviorTest {
|
|||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
||||||
BigInteger b = ff.getEncoding(ff.getBigFloat(1.5d));
|
BigInteger b = ff.getEncoding(ff.getBigFloat(1.5d));
|
||||||
BigInteger result = op.evaluateBinary(8, 8, a, b);
|
BigInteger result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigFloat(3.75d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(3.75d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigInfinityEncoding(false);
|
b = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigNaNEncoding(false);
|
b = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateBinary(8, 8, a, b);
|
result = op.evaluateBinary(8, 8, a, b);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -38,23 +38,23 @@ public class OpBehaviorFloatNegTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long a = ff.getEncoding(2.5);
|
long a = ff.getEncoding(2.5);
|
||||||
long result = op.evaluateUnary(8, 8, a);
|
long result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-2.5, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.5, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.5);
|
a = ff.getEncoding(-2.5);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(2.5, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -66,23 +66,23 @@ public class OpBehaviorFloatNegTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
||||||
BigInteger result = op.evaluateUnary(8, 8, a);
|
BigInteger result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.5d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.5d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(false);
|
a = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -38,39 +38,39 @@ public class OpBehaviorFloatRoundTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long a = ff.getEncoding(2.5);
|
long a = ff.getEncoding(2.5);
|
||||||
long result = op.evaluateUnary(8, 8, a);
|
long result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(3.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(3.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(2.25);
|
a = ff.getEncoding(2.25);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(2.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(2.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(2.75);
|
a = ff.getEncoding(2.75);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(3.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(3.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.5);
|
a = ff.getEncoding(-2.5);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-2.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.25);
|
a = ff.getEncoding(-2.25);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-2.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-2.75);
|
a = ff.getEncoding(-2.75);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(-3.0, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-3.0, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -82,39 +82,39 @@ public class OpBehaviorFloatRoundTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d));
|
||||||
BigInteger result = op.evaluateUnary(8, 8, a);
|
BigInteger result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(3.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(3.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(2.25d));
|
a = ff.getEncoding(ff.getBigFloat(2.25d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(2.75d));
|
a = ff.getEncoding(ff.getBigFloat(2.75d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(3.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(3.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
a = ff.getEncoding(ff.getBigFloat(-2.5d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.25d));
|
a = ff.getEncoding(ff.getBigFloat(-2.25d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-2.75d));
|
a = ff.getEncoding(ff.getBigFloat(-2.75d));
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigFloat(-3.0d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-3.0d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(false);
|
a = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
result = op.evaluateUnary(8, 8, a);
|
result = op.evaluateUnary(8, 8, a);
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -37,7 +37,7 @@ public class OpBehaviorFloatSqrtTest extends AbstractOpBehaviorTest {
|
|||||||
|
|
||||||
long longbits = ff.getEncoding(2.0);
|
long longbits = ff.getEncoding(2.0);
|
||||||
longbits = op.evaluateUnary(8, 8, longbits);
|
longbits = op.evaluateUnary(8, 8, longbits);
|
||||||
double d = ff.getHostFloat(longbits);
|
double d = ff.decodeHostFloat(longbits);
|
||||||
Assert.assertEquals("1.414213562373095", Double.toString(d).substring(0, 17));
|
Assert.assertEquals("1.414213562373095", Double.toString(d).substring(0, 17));
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ public class OpBehaviorFloatSqrtTest extends AbstractOpBehaviorTest {
|
|||||||
BigFloat big = ff.getBigFloat(2.0);
|
BigFloat big = ff.getBigFloat(2.0);
|
||||||
BigInteger encoding = ff.getEncoding(big);
|
BigInteger encoding = ff.getEncoding(big);
|
||||||
encoding = op.evaluateUnary(8, 8, encoding);
|
encoding = op.evaluateUnary(8, 8, encoding);
|
||||||
BigFloat result = ff.getHostFloat(encoding);
|
BigFloat result = ff.decodeBigFloat(encoding);
|
||||||
Assert.assertEquals("1.414213562373095", ff.round(result).toString());
|
Assert.assertEquals("1.414213562373095", ff.round(result).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -39,32 +39,32 @@ public class OpBehaviorFloatSubTest extends AbstractOpBehaviorTest {
|
|||||||
long a = ff.getEncoding(1.5);
|
long a = ff.getEncoding(1.5);
|
||||||
long b = ff.getEncoding(1.25);
|
long b = ff.getEncoding(1.25);
|
||||||
long result = op.evaluateBinary(8, 8, a, b);// 1.5 - 1.25
|
long result = op.evaluateBinary(8, 8, a, b);// 1.5 - 1.25
|
||||||
Assert.assertEquals(0.25, ff.getHostFloat(result), 0);
|
Assert.assertEquals(0.25, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(-1.25);
|
a = ff.getEncoding(-1.25);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -1.25 - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// -1.25 - 1.25
|
||||||
Assert.assertEquals(-2.5, ff.getHostFloat(result), 0);
|
Assert.assertEquals(-2.5, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
a = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// +INFINITY - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// +INFINITY - 1.25
|
||||||
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
a = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - 1.25
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
b = ff.getEncoding(Double.NEGATIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - -INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - -INFINITY
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
b = ff.getEncoding(Double.POSITIVE_INFINITY);
|
b = ff.getEncoding(Double.POSITIVE_INFINITY);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - +INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - +INFINITY
|
||||||
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0);
|
||||||
|
|
||||||
a = ff.getEncoding(Double.NaN);
|
a = ff.getEncoding(Double.NaN);
|
||||||
b = ff.getEncoding(1.25);
|
b = ff.getEncoding(1.25);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// NaN - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// NaN - 1.25
|
||||||
Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0);
|
Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -77,32 +77,32 @@ public class OpBehaviorFloatSubTest extends AbstractOpBehaviorTest {
|
|||||||
BigInteger a = ff.getEncoding(ff.getBigFloat(1.5d));
|
BigInteger a = ff.getEncoding(ff.getBigFloat(1.5d));
|
||||||
BigInteger b = ff.getEncoding(ff.getBigFloat(1.25d));
|
BigInteger b = ff.getEncoding(ff.getBigFloat(1.25d));
|
||||||
BigInteger result = op.evaluateBinary(8, 8, a, b);// 1.5 - 1.25
|
BigInteger result = op.evaluateBinary(8, 8, a, b);// 1.5 - 1.25
|
||||||
Assert.assertEquals(ff.getBigFloat(0.25d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(0.25d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getEncoding(ff.getBigFloat(-1.25d));
|
a = ff.getEncoding(ff.getBigFloat(-1.25d));
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -1.25 - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// -1.25 - 1.25
|
||||||
Assert.assertEquals(ff.getBigFloat(-2.5d), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigFloat(-2.5d), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(false);
|
a = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// +INFINITY - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// +INFINITY - 1.25
|
||||||
Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigInfinityEncoding(true);
|
a = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - 1.25
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigInfinityEncoding(true);
|
b = ff.getBigInfinityEncoding(true);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - -INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - -INFINITY
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
b = ff.getBigInfinityEncoding(false);
|
b = ff.getBigInfinityEncoding(false);
|
||||||
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - +INFINITY
|
result = op.evaluateBinary(8, 8, a, b);// -INFINITY - +INFINITY
|
||||||
Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
a = ff.getBigNaNEncoding(false);
|
a = ff.getBigNaNEncoding(false);
|
||||||
b = ff.getEncoding(ff.getBigFloat(1.25d));
|
b = ff.getEncoding(ff.getBigFloat(1.25d));
|
||||||
result = op.evaluateBinary(8, 8, a, b);// NaN - 1.25
|
result = op.evaluateBinary(8, 8, a, b);// NaN - 1.25
|
||||||
Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result));
|
Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -57,7 +57,8 @@ public class ProgramProviderContext implements DataTypeProviderContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DataType dt = data.getDataType();
|
DataType dt = data.getDataType();
|
||||||
int length = data.getLength();
|
int length = DataTypeComponentImpl.getPreferredComponentLength(dt,
|
||||||
|
Math.max(data.getLength(), dt.getAlignedLength()));
|
||||||
String label = null;
|
String label = null;
|
||||||
Symbol symbol = data.getPrimarySymbol();
|
Symbol symbol = data.getPrimarySymbol();
|
||||||
if (symbol != null && !symbol.isDynamic()) {
|
if (symbol != null && !symbol.isDynamic()) {
|
||||||
|
|||||||
+194
-43
@@ -15,8 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.pcode.floatformat;
|
package ghidra.pcode.floatformat;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.*;
|
||||||
import java.math.BigInteger;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An IEEE 754 floating point class.
|
* An IEEE 754 floating point class.
|
||||||
@@ -31,8 +32,20 @@ import java.math.BigInteger;
|
|||||||
*
|
*
|
||||||
* <p>Operations compute exact result then round to nearest even.
|
* <p>Operations compute exact result then round to nearest even.
|
||||||
*/
|
*/
|
||||||
public strictfp class BigFloat implements Comparable<BigFloat> {
|
public class BigFloat implements Comparable<BigFloat> {
|
||||||
final int fracbits; // there are fracbits+1 significant bits.
|
|
||||||
|
public static final String INFINITY = "Infinity";
|
||||||
|
public static final String POSITIVE_INFINITY = "+" + INFINITY;
|
||||||
|
public static final String NEGATIVE_INFINITY = "-" + INFINITY;
|
||||||
|
public static final String NAN = "NaN";
|
||||||
|
|
||||||
|
private static final int INFINITE_SCALE = -(64 * 1024);
|
||||||
|
public static final BigDecimal BIG_POSITIVE_INFINITY =
|
||||||
|
new BigDecimal(BigInteger.ONE, INFINITE_SCALE);
|
||||||
|
public static final BigDecimal BIG_NEGATIVE_INFINITY =
|
||||||
|
(new BigDecimal(BigInteger.ONE, INFINITE_SCALE)).negate();
|
||||||
|
|
||||||
|
final int fracbits; // number of significant mantissa bits including implied msb if relavent
|
||||||
final int expbits; // # bits used for exponent
|
final int expbits; // # bits used for exponent
|
||||||
|
|
||||||
final int maxScale;
|
final int maxScale;
|
||||||
@@ -40,19 +53,22 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
|
|
||||||
FloatKind kind;
|
FloatKind kind;
|
||||||
|
|
||||||
// -1, +1
|
int sign; // -1, +1
|
||||||
int sign;
|
|
||||||
// normal numbers have unscaled.bitLength() = fracbits+1
|
// normal numbers have unscaled.bitLength() = fracbits+1
|
||||||
// subnormal numbers have scale=0 and unscaled.bitLength() <= fracbits
|
// subnormal numbers have scale=0 and unscaled.bitLength() <= fracbits
|
||||||
BigInteger unscaled;
|
BigInteger unscaled;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
|
private static Map<Integer, MathContext> defaultDisplayContextMap = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a BigFloat. If kind is FINITE, the value is <code>sign*unscaled*2^(scale-fracbits)</code>.
|
* Construct a BigFloat. If kind is FINITE, the value is <code>sign*unscaled*2^(scale-fracbits)</code>.
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: Requires that normal values are constructed in a normal form as with denormal values.
|
* NOTE: Requires that normal values are constructed in a normal form as with denormal values.
|
||||||
*
|
*
|
||||||
* @param fracbits number of fractional bits (positive non-zero value)
|
* @param fracbits number of fractional bits (positive non-zero value; includes additional
|
||||||
|
* implied bit if relavent).
|
||||||
* @param expbits maximum number of bits in exponent (positive non-zero value)
|
* @param expbits maximum number of bits in exponent (positive non-zero value)
|
||||||
* @param kind the Kind, FINITE, INFINITE, ...
|
* @param kind the Kind, FINITE, INFINITE, ...
|
||||||
* @param sign +1 or -1
|
* @param sign +1 or -1
|
||||||
@@ -71,8 +87,8 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
this.maxScale = (1 << (expbits - 1)) - 1;
|
this.maxScale = (1 << (expbits - 1)) - 1;
|
||||||
this.minScale = 1 - this.maxScale;
|
this.minScale = 1 - this.maxScale;
|
||||||
|
|
||||||
if (unscaled.bitLength() > (fracbits + 1)) {
|
if (unscaled.bitLength() > fracbits) {
|
||||||
throw new IllegalArgumentException("unscaled value exceeds " + (fracbits + 1) +
|
throw new IllegalArgumentException("unscaled value exceeds " + fracbits +
|
||||||
" bits in length (length=" + unscaled.bitLength() + ")");
|
" bits in length (length=" + unscaled.bitLength() + ")");
|
||||||
}
|
}
|
||||||
if (scale < minScale || scale > maxScale) {
|
if (scale < minScale || scale > maxScale) {
|
||||||
@@ -182,7 +198,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
*/
|
*/
|
||||||
public static BigFloat infinity(int fracbits, int expbits, int sign) {
|
public static BigFloat infinity(int fracbits, int expbits, int sign) {
|
||||||
return new BigFloat(fracbits, expbits, FloatKind.INFINITE, sign,
|
return new BigFloat(fracbits, expbits, FloatKind.INFINITE, sign,
|
||||||
BigInteger.ONE.shiftLeft(fracbits), (1 << (expbits - 1)) - 1);
|
BigInteger.ONE.shiftLeft(fracbits - 1), (1 << (expbits - 1)) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,7 +239,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
* @return {@code true} if this BigFloat is FINITE and normal.
|
* @return {@code true} if this BigFloat is FINITE and normal.
|
||||||
*/
|
*/
|
||||||
public boolean isNormal() {
|
public boolean isNormal() {
|
||||||
return kind == FloatKind.FINITE && unscaled.bitLength() == (fracbits + 1);
|
return kind == FloatKind.FINITE && unscaled.bitLength() == fracbits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,7 +252,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
*/
|
*/
|
||||||
public boolean isDenormal() {
|
public boolean isDenormal() {
|
||||||
return kind == FloatKind.FINITE && !unscaled.equals(BigInteger.ZERO) &&
|
return kind == FloatKind.FINITE && !unscaled.equals(BigInteger.ZERO) &&
|
||||||
unscaled.bitLength() <= fracbits;
|
unscaled.bitLength() < fracbits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,7 +279,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int extrabits = Math.max(unscaled.bitLength() - (fracbits + 1), minScale - scale);
|
int extrabits = Math.max(unscaled.bitLength() - fracbits, minScale - scale);
|
||||||
|
|
||||||
if (extrabits <= 0) {
|
if (extrabits <= 0) {
|
||||||
throw new AssertionError("Rounding with no extra bits of precision");
|
throw new AssertionError("Rounding with no extra bits of precision");
|
||||||
@@ -279,7 +295,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
if (midbitset && (eps || odd)) {
|
if (midbitset && (eps || odd)) {
|
||||||
unscaled = unscaled.add(BigInteger.ONE);
|
unscaled = unscaled.add(BigInteger.ONE);
|
||||||
// handle overflowing carry
|
// handle overflowing carry
|
||||||
if (unscaled.bitLength() > fracbits + 1) {
|
if (unscaled.bitLength() > fracbits) {
|
||||||
assert (unscaled.bitLength() == unscaled.getLowestSetBit() + 1);
|
assert (unscaled.bitLength() == unscaled.getLowestSetBit() + 1);
|
||||||
unscaled = unscaled.shiftRight(1);
|
unscaled = unscaled.shiftRight(1);
|
||||||
scale += 1;
|
scale += 1;
|
||||||
@@ -295,14 +311,15 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
if (kind != FloatKind.FINITE || unscaled.signum() == 0) {
|
if (kind != FloatKind.FINITE || unscaled.signum() == 0) {
|
||||||
throw new AssertionError("lead bit of non-finite or zero");
|
throw new AssertionError("lead bit of non-finite or zero");
|
||||||
}
|
}
|
||||||
return unscaled.bitLength() - fracbits + scale;
|
return unscaled.bitLength() - fracbits + scale + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If finite, the returned BigDecimal is exactly equal to this. If not finite, one of the
|
* If finite, the returned BigDecimal is exactly equal to this. If not finite, one of the
|
||||||
* FloatFormat.BIG_* constants is returned.
|
* FloatFormat.BIG_* constants is returned.
|
||||||
*
|
*
|
||||||
* @return a BigDecimal
|
* @return a BigDecimal or null if value is NaN (i.e., {@link FloatKind#QUIET_NAN} or
|
||||||
|
* {@link FloatKind#SIGNALING_NAN}).
|
||||||
*/
|
*/
|
||||||
public BigDecimal toBigDecimal() {
|
public BigDecimal toBigDecimal() {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
@@ -312,7 +329,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
}
|
}
|
||||||
int unusedBits = Math.max(unscaled.getLowestSetBit(), 0);
|
int unusedBits = Math.max(unscaled.getLowestSetBit(), 0);
|
||||||
BigInteger val = unscaled;
|
BigInteger val = unscaled;
|
||||||
int iscale = scale - fracbits;
|
int iscale = scale - fracbits + 1;
|
||||||
BigDecimal x;
|
BigDecimal x;
|
||||||
if (iscale >= -unusedBits) {
|
if (iscale >= -unusedBits) {
|
||||||
x = new BigDecimal(val.shiftLeft(iscale));
|
x = new BigDecimal(val.shiftLeft(iscale));
|
||||||
@@ -330,11 +347,10 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
case INFINITE:
|
case INFINITE:
|
||||||
return sign < 0 ? FloatFormat.BIG_NEGATIVE_INFINITY
|
return sign < 0 ? BIG_NEGATIVE_INFINITY : BIG_POSITIVE_INFINITY;
|
||||||
: FloatFormat.BIG_POSITIVE_INFINITY;
|
|
||||||
case QUIET_NAN:
|
case QUIET_NAN:
|
||||||
case SIGNALING_NAN:
|
case SIGNALING_NAN:
|
||||||
return FloatFormat.BIG_NaN;
|
return null;
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("unknown BigFloat kind: " + kind);
|
throw new AssertionError("unknown BigFloat kind: " + kind);
|
||||||
}
|
}
|
||||||
@@ -359,15 +375,16 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
String binary;
|
String binary;
|
||||||
if (this.isNormal()) {
|
if (this.isNormal()) {
|
||||||
binary = "1." + unscaled.toString(2).substring(1);
|
binary = "1." + unscaled.toString(2).substring(1);
|
||||||
ascale += (unscaled.bitLength() - (fracbits + 1));
|
ascale += (unscaled.bitLength() - fracbits);
|
||||||
}
|
}
|
||||||
else { // subnormal
|
else { // subnormal
|
||||||
assert (unscaled.bitLength() <= fracbits);
|
assert (unscaled.bitLength() < fracbits);
|
||||||
if (unscaled.equals(BigInteger.ZERO)) {
|
if (unscaled.equals(BigInteger.ZERO)) {
|
||||||
return String.format("%s0b0.0", s);
|
return String.format("%s0b0.0", s);
|
||||||
}
|
}
|
||||||
binary =
|
binary =
|
||||||
"0." + "0".repeat(fracbits - unscaled.bitLength()) + unscaled.toString(2);
|
"0." + "0".repeat(fracbits - unscaled.bitLength() - 1) +
|
||||||
|
unscaled.toString(2);
|
||||||
}
|
}
|
||||||
binary = binary.replaceAll("0*$", "");
|
binary = binary.replaceAll("0*$", "");
|
||||||
if (binary.endsWith(".")) {
|
if (binary.endsWith(".")) {
|
||||||
@@ -497,7 +514,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
// nbits(x) - nbits(y) <= nbits(x/y) <= nbits(x) - nbits(y) + 1
|
// nbits(x) - nbits(y) <= nbits(x/y) <= nbits(x) - nbits(y) + 1
|
||||||
// so
|
// so
|
||||||
// this + lshift - other = fracbits+2 =>
|
// this + lshift - other = fracbits+2 =>
|
||||||
int lshift = fracbits + 2 + other.unscaled.bitLength() - this.unscaled.bitLength();
|
int lshift = fracbits + 1 + other.unscaled.bitLength() - this.unscaled.bitLength();
|
||||||
this.upscale(lshift);
|
this.upscale(lshift);
|
||||||
|
|
||||||
BigInteger qr[] = this.unscaled.divideAndRemainder(other.unscaled);
|
BigInteger qr[] = this.unscaled.divideAndRemainder(other.unscaled);
|
||||||
@@ -505,7 +522,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
BigInteger r = qr[1];
|
BigInteger r = qr[1];
|
||||||
|
|
||||||
this.sign *= other.sign;
|
this.sign *= other.sign;
|
||||||
this.scale -= other.scale - fracbits;
|
this.scale -= other.scale - fracbits + 1;
|
||||||
this.unscaled = q;
|
this.unscaled = q;
|
||||||
this.internalRound(r.signum() != 0);
|
this.internalRound(r.signum() != 0);
|
||||||
}
|
}
|
||||||
@@ -545,9 +562,9 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
// this and other are finite
|
// this and other are finite
|
||||||
this.sign *= other.sign;
|
this.sign *= other.sign;
|
||||||
this.unscaled = this.unscaled.multiply(other.unscaled);
|
this.unscaled = this.unscaled.multiply(other.unscaled);
|
||||||
this.scale += other.scale - fracbits;
|
this.scale += other.scale - fracbits + 1;
|
||||||
|
|
||||||
this.scaleUpTo(fracbits + 2);
|
this.scaleUpTo(fracbits + 1);
|
||||||
this.internalRound(false);
|
this.internalRound(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,10 +656,10 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
protected void add0(BigFloat other) {
|
protected void add0(BigFloat other) {
|
||||||
int d = this.scale - other.scale;
|
int d = this.scale - other.scale;
|
||||||
|
|
||||||
if (d > fracbits + 1) {
|
if (d > fracbits) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (d < -(fracbits + 1)) {
|
else if (d < -fracbits) {
|
||||||
this.copyFrom(other);
|
this.copyFrom(other);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -664,7 +681,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
this.scale = a.scale - 1;
|
this.scale = a.scale - 1;
|
||||||
this.unscaled = a.unscaled.shiftLeft(1).add(b.unscaled.shiftRight(d - 1));
|
this.unscaled = a.unscaled.shiftLeft(1).add(b.unscaled.shiftRight(d - 1));
|
||||||
|
|
||||||
scaleUpTo(fracbits + 2);
|
scaleUpTo(fracbits + 1);
|
||||||
internalRound(residue);
|
internalRound(residue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,10 +689,10 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
protected void sub0(BigFloat other) {
|
protected void sub0(BigFloat other) {
|
||||||
int d = this.scale - other.scale;
|
int d = this.scale - other.scale;
|
||||||
|
|
||||||
if (d > fracbits + 2) {
|
if (d > fracbits + 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (d < -(fracbits + 2)) {
|
else if (d < -(fracbits + 1)) {
|
||||||
this.copyFrom(other);
|
this.copyFrom(other);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -710,7 +727,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
this.sign *= -1;
|
this.sign *= -1;
|
||||||
this.unscaled = this.unscaled.negate();
|
this.unscaled = this.unscaled.negate();
|
||||||
}
|
}
|
||||||
scaleUpTo(fracbits + 2);
|
scaleUpTo(fracbits + 1);
|
||||||
internalRound(residue);
|
internalRound(residue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,11 +768,11 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
BigInteger bit;
|
BigInteger bit;
|
||||||
|
|
||||||
//// force at least fracbits+2 bits of precision in the result
|
//// force at least fracbits+2 bits of precision in the result
|
||||||
int sigbits = 2 * fracbits + 3;
|
int sigbits = 2 * fracbits + 2;
|
||||||
this.scaleUpTo(sigbits);
|
this.scaleUpTo(sigbits);
|
||||||
|
|
||||||
// scale+fracbits needs to be even for the sqrt computation
|
// scale+fracbits needs to be even for the sqrt computation
|
||||||
if (((scale + fracbits) & 1) != 0) {
|
if (((scale + fracbits - 1) & 1) != 0) {
|
||||||
upscale(1);
|
upscale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,7 +795,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unscaled = result;
|
unscaled = result;
|
||||||
scale = (scale + fracbits) / 2;
|
scale = (scale + fracbits - 1) / 2;
|
||||||
|
|
||||||
internalRound(residue.signum() != 0);
|
internalRound(residue.signum() != 0);
|
||||||
}
|
}
|
||||||
@@ -790,7 +807,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
makeZero();
|
makeZero();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int nbitsUnderOne = fracbits - scale;
|
int nbitsUnderOne = fracbits - scale - 1;
|
||||||
unscaled = unscaled.shiftRight(nbitsUnderOne).shiftLeft(nbitsUnderOne);
|
unscaled = unscaled.shiftRight(nbitsUnderOne).shiftLeft(nbitsUnderOne);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +815,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
private void makeOne() {
|
private void makeOne() {
|
||||||
kind = FloatKind.FINITE;
|
kind = FloatKind.FINITE;
|
||||||
scale = 0;
|
scale = 0;
|
||||||
unscaled = BigInteger.ONE.shiftLeft(fracbits);
|
unscaled = BigInteger.ONE.shiftLeft(fracbits - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ceil, ignoring sign
|
// ceil, ignoring sign
|
||||||
@@ -811,7 +828,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nbitsUnderOne = fracbits - scale;
|
int nbitsUnderOne = fracbits - scale - 1;
|
||||||
boolean increment = unscaled.getLowestSetBit() < nbitsUnderOne;
|
boolean increment = unscaled.getLowestSetBit() < nbitsUnderOne;
|
||||||
unscaled = unscaled.shiftRight(nbitsUnderOne).shiftLeft(nbitsUnderOne);
|
unscaled = unscaled.shiftRight(nbitsUnderOne).shiftLeft(nbitsUnderOne);
|
||||||
if (increment) {
|
if (increment) {
|
||||||
@@ -819,7 +836,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we carry to a new bit, change the scale
|
// if we carry to a new bit, change the scale
|
||||||
if (unscaled.bitLength() > fracbits + 1) {
|
if (unscaled.bitLength() > fracbits) {
|
||||||
upscale(-1);
|
upscale(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -945,7 +962,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
* @return the truncated integer form of this BigFloat
|
* @return the truncated integer form of this BigFloat
|
||||||
*/
|
*/
|
||||||
public BigInteger toBigInteger() {
|
public BigInteger toBigInteger() {
|
||||||
BigInteger res = unscaled.shiftRight(fracbits - scale);
|
BigInteger res = unscaled.shiftRight(fracbits - scale - 1);
|
||||||
if (sign < 0) {
|
if (sign < 0) {
|
||||||
return res.negate();
|
return res.negate();
|
||||||
}
|
}
|
||||||
@@ -967,7 +984,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
*/
|
*/
|
||||||
public void round() {
|
public void round() {
|
||||||
BigFloat half = new BigFloat(fracbits, expbits, FloatKind.FINITE, +1,
|
BigFloat half = new BigFloat(fracbits, expbits, FloatKind.FINITE, +1,
|
||||||
BigInteger.ONE.shiftLeft(fracbits), -1);
|
BigInteger.ONE.shiftLeft(fracbits - 1), -1);
|
||||||
add(half);
|
add(half);
|
||||||
floor();
|
floor();
|
||||||
}
|
}
|
||||||
@@ -1018,4 +1035,138 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||||||
return this.sign * this.unscaled.compareTo(other.unscaled);
|
return this.sign * this.unscaled.compareTo(other.unscaled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatSpecialCase() {
|
||||||
|
if (isNaN()) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
if (isInfinite()) {
|
||||||
|
return sign < 0 ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform rounding and conversion to BigDecimal prior to generating
|
||||||
|
* a formatted decimal string of the specified BigFloat value.
|
||||||
|
* A default generated {@link MathContext} is used.
|
||||||
|
* @return decimal string representation
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String special = formatSpecialCase();
|
||||||
|
if (special != null) {
|
||||||
|
return special;
|
||||||
|
}
|
||||||
|
BigDecimal bd = toBigDecimal();
|
||||||
|
bd = bd.round(getDefaultDisplayContext(fracbits));
|
||||||
|
return bd.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform rounding and conversion to BigDecimal prior to generating
|
||||||
|
* a formatted decimal string of the specified BigFloat value.
|
||||||
|
* @param displayContext display context used for rounding and precision.
|
||||||
|
* @return decimal string representation
|
||||||
|
*/
|
||||||
|
public String toString(MathContext displayContext) {
|
||||||
|
String special = formatSpecialCase();
|
||||||
|
if (special != null) {
|
||||||
|
return special;
|
||||||
|
}
|
||||||
|
BigDecimal bd = toBigDecimal();
|
||||||
|
bd = bd.round(displayContext);
|
||||||
|
return bd.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform appropriate rounding and conversion to BigDecimal prior to generating
|
||||||
|
* a formatted decimal string of the specified BigFloat value.
|
||||||
|
* See {@link #toString(FloatFormat, boolean)},
|
||||||
|
* {@link FloatFormat#toDecimalString(BigFloat)} and
|
||||||
|
* {@link FloatFormat#toDecimalString(BigFloat, boolean)}.
|
||||||
|
* @param ff float format
|
||||||
|
* @param compact if true the precision will be reduced to a form which is still equivalent at
|
||||||
|
* the binary encoding level for the specified FloatFormat.
|
||||||
|
* @return decimal string representation
|
||||||
|
*/
|
||||||
|
public String toString(FloatFormat ff, boolean compact) {
|
||||||
|
String special = formatSpecialCase();
|
||||||
|
if (special != null) {
|
||||||
|
return special;
|
||||||
|
}
|
||||||
|
BigDecimal bd = toBigDecimal();
|
||||||
|
bd = bd.round(ff.getDisplayContext());
|
||||||
|
|
||||||
|
String str = bd.toString();
|
||||||
|
int precision = bd.precision();
|
||||||
|
int bdScale = bd.scale();
|
||||||
|
|
||||||
|
// Generate compact representation if requested
|
||||||
|
if (compact && precision > 2) {
|
||||||
|
BigInteger encoding = ff.getEncoding(this);
|
||||||
|
for (String newStr = str; newStr != null;) {
|
||||||
|
newStr = removeFractionalDigit(newStr, 1, false);
|
||||||
|
if (newStr != null) {
|
||||||
|
bd = new BigDecimal(newStr);
|
||||||
|
bd = bd.setScale(bdScale); // avoid scale change which may alter encoding
|
||||||
|
BigFloat bf = ff.getBigFloat(bd);
|
||||||
|
if (encoding.equals(ff.getEncoding(bf))) {
|
||||||
|
str = newStr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newStr = null; // stop compaction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Strip trailing zeros
|
||||||
|
str = stripTrailingZeros(str, 1);
|
||||||
|
// Ensure decimal point is present
|
||||||
|
if (str.indexOf('.') < 0) {
|
||||||
|
str += ".0";
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stripTrailingZeros(String decStr, int minDigits) {
|
||||||
|
String str = decStr;
|
||||||
|
while (true) {
|
||||||
|
String nextStr = removeFractionalDigit(str, 1, true);
|
||||||
|
if (nextStr == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str = nextStr;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeFractionalDigit(String decStr, int minDigits, boolean stripZeroDigitOnly) {
|
||||||
|
int decimalPointIx = decStr.indexOf('.');
|
||||||
|
if (decimalPointIx < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int expIx = decStr.toUpperCase().indexOf('E');
|
||||||
|
String exp = "";
|
||||||
|
if (expIx > 0) {
|
||||||
|
exp = decStr.substring(expIx);
|
||||||
|
decStr = decStr.substring(0, expIx);
|
||||||
|
}
|
||||||
|
if (decStr.length() - decimalPointIx - 1 <= minDigits) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int lastDigitIndex = decStr.length() - 1;
|
||||||
|
if (stripZeroDigitOnly && decStr.charAt(lastDigitIndex) != '0') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// discard last mantissa digit
|
||||||
|
return decStr.substring(0, lastDigitIndex) + exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized MathContext getDefaultDisplayContext(int fracBits) {
|
||||||
|
return defaultDisplayContextMap.computeIfAbsent(fracBits, n -> {
|
||||||
|
int precision = (int) (0.30103 * fracBits); // log10(2) * mantissa bits
|
||||||
|
return new MathContext(precision, RoundingMode.HALF_EVEN);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user