From 1fac0a2993d796255deb5c8374be48bcef107e5e Mon Sep 17 00:00:00 2001 From: Alex Bertram Date: Fri, 27 Oct 2017 00:41:45 +0200 Subject: [PATCH] Provide (faked) support for 96-bit floating point values. Just use 64-bit doubles. Unfortunately, I can't find a way to configure GCC 4.7 to use a smaller size for the "long double" type, so we have to play some games with pointers. --- .../renjin/gcc/codegen/expr/BinaryOpExpr.java | 72 +++++++++++ .../renjin/gcc/codegen/expr/Expressions.java | 52 +------- .../codegen/type/primitive/PrimitiveType.java | 29 +++++ .../primitive/PrimitiveValueFunction.java | 9 +- .../gcc/codegen/type/primitive/RealExpr.java | 8 +- .../renjin/gcc/codegen/vptr/DerefExpr.java | 30 +++-- .../renjin/gcc/codegen/vptr/PointerType.java | 12 ++ .../org/renjin/gcc/GimpleCompilerTest.java | 5 + .../test/resources/org/renjin/gcc/real96.c | 32 +++++ .../org/renjin/gcc/runtime/AbstractPtr.java | 34 ++++++ .../org/renjin/gcc/runtime/Double96Ptr.java | 114 ++++++++++++++++++ .../org/renjin/gcc/runtime/OffsetPtr.java | 30 +++++ .../org/renjin/gcc/runtime/OpaquePtr.java | 30 +++++ .../main/java/org/renjin/gcc/runtime/Ptr.java | 35 ++++++ .../org/renjin/gcc/runtime/RecordUnitPtr.java | 30 +++++ .../renjin/gcc/runtime/RecordUnitPtrPtr.java | 30 +++++ 16 files changed, 482 insertions(+), 70 deletions(-) create mode 100644 tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/BinaryOpExpr.java create mode 100644 tools/gcc-bridge/compiler/src/test/resources/org/renjin/gcc/real96.c create mode 100644 tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Double96Ptr.java diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/BinaryOpExpr.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/BinaryOpExpr.java new file mode 100644 index 0000000000..7744c1d33c --- /dev/null +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/BinaryOpExpr.java @@ -0,0 +1,72 @@ +/** + * Renjin : JVM-based interpreter for the R language for the statistical analysis + * Copyright © 2010-2016 BeDataDriven Groep B.V. and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, a copy is available at + * https://www.gnu.org/licenses/gpl-2.0.txt + */ +package org.renjin.gcc.codegen.expr; + +import org.renjin.gcc.codegen.MethodGenerator; +import org.renjin.repackaged.asm.Type; + +import javax.annotation.Nonnull; + +public class BinaryOpExpr implements JExpr { + + private int opcode; + private Type resultType; + private JExpr x; + private JExpr y; + + + public BinaryOpExpr(int opcode, JExpr x, JExpr y) { + this.opcode = opcode; + this.resultType = x.getType(); + this.x = x; + this.y = y; + } + + public BinaryOpExpr(int opcode, Type resultType, JExpr x, JExpr y) { + this.opcode = opcode; + this.resultType = resultType; + this.x = x; + this.y = y; + } + + public int getOpcode() { + return opcode; + } + + public JExpr getX() { + return x; + } + + public JExpr getY() { + return y; + } + + @Nonnull + @Override + public Type getType() { + return resultType; + } + + @Override + public void load(@Nonnull MethodGenerator mv) { + x.load(mv); + y.load(mv); + mv.visitInsn(x.getType().getOpcode(opcode)); + } +} diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/Expressions.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/Expressions.java index e5c3c770bd..d0946a3977 100644 --- a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/Expressions.java +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/expr/Expressions.java @@ -192,20 +192,7 @@ public static JExpr zero(final Type type) { } private static JExpr binary(final int opcode, final JExpr x, final JExpr y, final Type resultType) { - return new JExpr() { - @Nonnull - @Override - public Type getType() { - return resultType; - } - - @Override - public void load(@Nonnull MethodGenerator mv) { - x.load(mv); - y.load(mv); - mv.visitInsn(x.getType().getOpcode(opcode)); - } - }; + return new BinaryOpExpr(opcode, resultType, x, y); } private static Type promoteSmallInts(Type type) { @@ -763,7 +750,7 @@ public static JExpr bitwiseXor(JExpr x, int y) { } public static JExpr bitwiseXor(JExpr x, JExpr y) { - return new BinaryOp(Opcodes.IXOR, x, y); + return new BinaryOpExpr(Opcodes.IXOR, x, y); } public static JExpr flip(JExpr value) { @@ -1109,39 +1096,4 @@ public void load(@Nonnull MethodGenerator mv) { }; } - private static class BinaryOp implements JExpr { - - private int opcode; - private Type resultType; - private JExpr x; - private JExpr y; - - - public BinaryOp(int opcode, JExpr x, JExpr y) { - this.opcode = opcode; - this.resultType = x.getType(); - this.x = x; - this.y = y; - } - - public BinaryOp(int opcode, Type resultType, JExpr x, JExpr y) { - this.opcode = opcode; - this.resultType = resultType; - this.x = x; - this.y = y; - } - - @Nonnull - @Override - public Type getType() { - return resultType; - } - - @Override - public void load(@Nonnull MethodGenerator mv) { - x.load(mv); - y.load(mv); - mv.visitInsn(x.getType().getOpcode(opcode)); - } - } } \ No newline at end of file diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveType.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveType.java index e436b898f1..1ae72d2f87 100644 --- a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveType.java +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveType.java @@ -90,6 +90,33 @@ public GExpr constantExpr(GimpleConstant expr) { return new RealExpr(gimpleType(), Expressions.constantDouble(((GimpleRealConstant) expr).getValue())); } }, + REAL96 { + + @Override + public GimpleRealType gimpleType() { + return new GimpleRealType(96); + } + + @Override + public Type jvmType() { + return Type.DOUBLE_TYPE; + } + + @Override + public PrimitiveExpr cast(PrimitiveExpr x) { + return x.toReal(96); + } + + @Override + public PrimitiveExpr fromStackValue(JExpr jExpr, @Nullable GExpr address) { + return new RealExpr(gimpleType(), jExpr, address); + } + + @Override + public GExpr constantExpr(GimpleConstant expr) { + return new RealExpr(gimpleType(), Expressions.constantDouble(((GimpleRealConstant) expr).getValue())); + } + }, BOOL { @Override public GimplePrimitiveType gimpleType() { @@ -383,6 +410,8 @@ public static PrimitiveType of(GimplePrimitiveType type) { return REAL32; case 64: return REAL64; + case 96: + return REAL96; } } else if(type instanceof GimpleIntegerType) { GimpleIntegerType integerType = (GimpleIntegerType) type; diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveValueFunction.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveValueFunction.java index b039883b0a..90e320bcea 100644 --- a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveValueFunction.java +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/PrimitiveValueFunction.java @@ -30,6 +30,7 @@ import org.renjin.gcc.codegen.vptr.VPtrExpr; import org.renjin.gcc.gimple.type.GimplePrimitiveType; import org.renjin.gcc.gimple.type.GimpleType; +import org.renjin.gcc.runtime.Double96Ptr; import org.renjin.repackaged.asm.Type; import org.renjin.repackaged.guava.base.Optional; @@ -112,8 +113,14 @@ public Optional getValueConstructor() { public VPtrExpr toVPtr(JExpr array, JExpr offset) { PointerType pointerType = PointerType.ofPrimitiveType(type.gimpleType()); - JExpr newWrapper = Expressions.newObject(pointerType.alignedImpl(), array, offset); + // Special handling for double[] -> Real96 + if(pointerType == PointerType.REAL96 && array.getType().getElementType().equals(Type.DOUBLE_TYPE)) { + JExpr newWrapper = Expressions.newObject(Type.getType(Double96Ptr.class), array, offset); + return new VPtrExpr(newWrapper); + } + + JExpr newWrapper = Expressions.newObject(pointerType.alignedImpl(), array, offset); return new VPtrExpr(newWrapper); } diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/RealExpr.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/RealExpr.java index 9840e11811..8ae9d580b0 100644 --- a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/RealExpr.java +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/type/primitive/RealExpr.java @@ -235,11 +235,13 @@ public ConditionGenerator compareTo(GimpleOp op, GExpr operand) { } private JExpr jexpr(int targetPrecision) { - if(this.getPrecision() == targetPrecision) { + if(this.getPrecision() == targetPrecision || + (this.getPrecision() == 64 && targetPrecision == 96) || + (this.getPrecision() == 96 && targetPrecision == 64)) { return jexpr(); - } else if(this.getPrecision() == 32 && targetPrecision == 64) { + } else if(this.getPrecision() == 32 && (targetPrecision == 64 || targetPrecision == 96)) { return Expressions.f2d(jexpr()); - } else if(this.getPrecision() == 64 && targetPrecision == 32) { + } else if((this.getPrecision() == 64 || this.getPrecision() == 96) && targetPrecision == 32) { return Expressions.d2f(jexpr()); } else { throw new IllegalArgumentException(getPrecision() + "=>" + targetPrecision); diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/DerefExpr.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/DerefExpr.java index 9cff714e46..16cbdd0d7e 100644 --- a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/DerefExpr.java +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/DerefExpr.java @@ -19,11 +19,9 @@ package org.renjin.gcc.codegen.vptr; import org.renjin.gcc.codegen.MethodGenerator; -import org.renjin.gcc.codegen.expr.ConstantValue; -import org.renjin.gcc.codegen.expr.Expressions; -import org.renjin.gcc.codegen.expr.JExpr; -import org.renjin.gcc.codegen.expr.JLValue; +import org.renjin.gcc.codegen.expr.*; import org.renjin.gcc.runtime.Ptr; +import org.renjin.repackaged.asm.Opcodes; import org.renjin.repackaged.asm.Type; import javax.annotation.Nonnull; @@ -106,18 +104,18 @@ private JExpr isAligned() { } } -// if(offsetBytes instanceof PrimitiveBinOpGenerator) { -// PrimitiveBinOpGenerator op = (PrimitiveBinOpGenerator) offsetBytes; -// if(op.getOpCode() == Opcodes.IMUL) { -// -// if(isConstantEqualTo(op.getX(), pointerType.getSize())) { -// return op.getY(); -// } -// if(isConstantEqualTo(op.getY(), pointerType.getSize())) { -// return op.getX(); -// } -// } -// } + if(offsetBytes instanceof BinaryOpExpr) { + BinaryOpExpr op = (BinaryOpExpr) offsetBytes; + if(op.getOpcode() == Opcodes.IMUL) { + + if(isConstantEqualTo(op.getX(), pointerType.getSize())) { + return op.getY(); + } + if(isConstantEqualTo(op.getY(), pointerType.getSize())) { + return op.getX(); + } + } + } return null; } diff --git a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/PointerType.java b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/PointerType.java index 5831eed57c..da55735d6d 100644 --- a/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/PointerType.java +++ b/tools/gcc-bridge/compiler/src/main/java/org/renjin/gcc/codegen/vptr/PointerType.java @@ -19,6 +19,7 @@ package org.renjin.gcc.codegen.vptr; import org.renjin.gcc.gimple.type.*; +import org.renjin.gcc.runtime.IntPtr; import org.renjin.gcc.runtime.Ptr; import org.renjin.repackaged.asm.Type; @@ -37,6 +38,12 @@ public enum PointerType { LONG(Type.LONG_TYPE, PointerKind.INTEGRAL, 8), FLOAT(Type.FLOAT_TYPE, PointerKind.FLOAT, 4), DOUBLE(Type.DOUBLE_TYPE, PointerKind.FLOAT, 8), + REAL96(Type.DOUBLE_TYPE, PointerKind.INTEGRAL, 12) { + @Override + public Type alignedImpl() { + return Type.getType(IntPtr.class); + } + }, POINTER(Type.getType(Ptr.class), PointerKind.POINTER, 4), FUNCTION(Type.getType(MethodHandle.class), PointerKind.FUNCTION, 4); @@ -69,6 +76,11 @@ public Type alignedImpl() { } public static PointerType ofPrimitiveType(GimplePrimitiveType primitiveType) { + if(primitiveType.equals(new GimpleRealType(96))) { + return REAL96; + } else if(primitiveType.equals(new GimpleRealType(64))) { + return DOUBLE; + } for (PointerType pointerType : values()) { if(pointerType.getJvmType().equals(primitiveType.jvmType())) { return pointerType; diff --git a/tools/gcc-bridge/compiler/src/test/java/org/renjin/gcc/GimpleCompilerTest.java b/tools/gcc-bridge/compiler/src/test/java/org/renjin/gcc/GimpleCompilerTest.java index 348d5888ce..d7cab1c680 100644 --- a/tools/gcc-bridge/compiler/src/test/java/org/renjin/gcc/GimpleCompilerTest.java +++ b/tools/gcc-bridge/compiler/src/test/java/org/renjin/gcc/GimpleCompilerTest.java @@ -1225,5 +1225,10 @@ public void fortranBooleanArg() throws Exception { public void sha256() throws Exception { compileAndTest("sha256.c"); } + + @Test + public void real96() throws Exception { + compileAndTest("real96.c"); + } } diff --git a/tools/gcc-bridge/compiler/src/test/resources/org/renjin/gcc/real96.c b/tools/gcc-bridge/compiler/src/test/resources/org/renjin/gcc/real96.c new file mode 100644 index 0000000000..f547e0f0c7 --- /dev/null +++ b/tools/gcc-bridge/compiler/src/test/resources/org/renjin/gcc/real96.c @@ -0,0 +1,32 @@ + +#include +#include + +#include "assert.h" + + +void test_real96() { + + long double x = 1/3; + long double y = 2/3; + + ASSERT( fabs((2.0*x) - y) < 0.00001); +} + +void test_real96_pointers() { + + long double a[6]; + a[0] = 100; + a[1] = 101; + a[2] = 102; + a[3] = 103; + a[4] = 104; + a[5] = 105; + + long double *pa = &a[0]; + long double *pb = &a[3]; + + ASSERT(*pa == 100); + ASSERT(*pb == 103); + ASSERT(pb[2] == 105); +} \ No newline at end of file diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/AbstractPtr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/AbstractPtr.java index c3380cc36c..6643ab1a3d 100644 --- a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/AbstractPtr.java +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/AbstractPtr.java @@ -110,6 +110,40 @@ public void setAlignedDouble(int index, double value) { setDouble(index * DoublePtr.BYTES, value); } + + @Override + public double getReal96() { + return getReal96(0); + } + + + @Override + public double getAlignedReal96(int index) { + return getReal96(index * 12); + } + + @Override + public double getReal96(int offset) { + return Double.longBitsToDouble(getLong(offset)); + } + + + @Override + public void setReal96(double value) { + setReal96(0, value); + } + + @Override + public void setAlignedReal96(int index, double value) { + setReal96(index * 12, value); + } + + @Override + public void setReal96(int offset, double value) { + setLong(offset, Double.doubleToRawLongBits(value)); + } + + @Override public char getChar() { return getChar(0); diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Double96Ptr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Double96Ptr.java new file mode 100644 index 0000000000..74a0614c18 --- /dev/null +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Double96Ptr.java @@ -0,0 +1,114 @@ +/** + * Renjin : JVM-based interpreter for the R language for the statistical analysis + * Copyright © 2010-2016 BeDataDriven Groep B.V. and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, a copy is available at + * https://www.gnu.org/licenses/gpl-2.0.txt + */ +package org.renjin.gcc.runtime; + +public class Double96Ptr extends AbstractPtr { + + public static final int BYTES = 12; + + private double[] array; + private int offset; + + public Double96Ptr(double[] array, int offset) { + this.array = array; + this.offset = offset; + } + + @Override + public Object getArray() { + return array; + } + + @Override + public int getOffsetInBytes() { + return offset * BYTES; + } + + @Override + public Ptr realloc(int newSizeInBytes) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public Ptr pointerPlus(int bytes) { + if(bytes % BYTES == 0) { + return new Double96Ptr(array, this.offset + (bytes / BYTES)); + } else { + return new OffsetPtr(this, bytes); + } + } + + @Override + public byte getByte(int offset) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setByte(int offset, byte value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getReal96() { + return this.array[this.offset]; + } + + @Override + public double getReal96(int offset) { + if(offset % BYTES == 0) { + return this.array[this.offset + (offset / BYTES)]; + } else { + return super.getReal96(offset); + } + } + + @Override + public double getAlignedReal96(int index) { + return this.array[this.offset + index]; + } + + @Override + public void setReal96(double value) { + this.array[this.offset] = value; + } + + @Override + public void setReal96(int offset, double value) { + if(offset % BYTES == 0) { + setAlignedReal96(this.offset + (offset / BYTES), value); + } else { + super.setAlignedReal96(offset, value); + } + } + + @Override + public void setAlignedReal96(int index, double value) { + this.array[this.offset + index] = value; + } + + @Override + public int toInt() { + return offset; + } + + @Override + public boolean isNull() { + return array == null && offset == 0; + } +} diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OffsetPtr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OffsetPtr.java index 5b40db1ebd..52a4ab4456 100644 --- a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OffsetPtr.java +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OffsetPtr.java @@ -187,6 +187,36 @@ public void setAlignedDouble(int index, double value) { ptr.setDouble(this.offset + (index * DoublePtr.BYTES), value); } + @Override + public double getReal96() { + return ptr.getReal96(this.offset); + } + + @Override + public double getReal96(int offset) { + return ptr.getReal96(this.offset + offset); + } + + @Override + public double getAlignedReal96(int index) { + return ptr.getReal96(this.offset + (index * Double96Ptr.BYTES)); + } + + @Override + public void setReal96(double value) { + ptr.setReal96(this.offset, value); + } + + @Override + public void setReal96(int offset, double value) { + ptr.setReal96(this.offset + offset, value); + } + + @Override + public void setAlignedReal96(int index, double value) { + ptr.setReal96(this.offset + (index * Double96Ptr.BYTES), value); + } + @Override public float getFloat() { return ptr.getFloat(this.offset); diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OpaquePtr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OpaquePtr.java index 7df09f26e6..4ee7fe2ae3 100644 --- a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OpaquePtr.java +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/OpaquePtr.java @@ -283,6 +283,36 @@ public void setAlignedDouble(int index, double value) { throw new UnsupportedOperationException("TODO"); } + @Override + public double getReal96() { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getReal96(int offset) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getAlignedReal96(int index) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setReal96(double value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setReal96(int offset, double value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setAlignedReal96(int index, double value) { + throw new UnsupportedOperationException("TODO"); + } + @Override public float getAlignedFloat(int index) { throw new UnsupportedOperationException("TODO"); diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Ptr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Ptr.java index c244a3c10a..37d6757bba 100644 --- a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Ptr.java +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/Ptr.java @@ -150,6 +150,41 @@ public interface Ptr extends Comparable { void setAlignedDouble(int index, double value); + + /** + * + * @return the value at the beginning of the pointer region as a double + */ + double getReal96(); + + /** + * + * @param offset the offset from the beginning of the pointer, in bytes. + * @return the float at the given offset from the beginning of the pointer region. + */ + double getReal96(int offset); + + /** + * @param index the index of the 8-byte double, from the beginning of the pointer. + */ + double getAlignedReal96(int index); + + /** + * Sets the given {@code value} at the beginning of the pointer. + */ + void setReal96(double value); + + + /** + * Sets the given {@code value} at the offset from the beginning of the pointer. + * @param offset the offset from the beginning of the pointer, in bytes. + */ + void setReal96(int offset, double value); + + + void setAlignedReal96(int index, double value); + + /** * * @return the value at the beginning of the pointer region as a float diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtr.java index 9e9f354359..47fefb5e91 100644 --- a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtr.java +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtr.java @@ -279,6 +279,36 @@ public void setAlignedDouble(int index, double value) { throw new UnsupportedOperationException("TODO"); } + @Override + public double getReal96() { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getReal96(int offset) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getAlignedReal96(int index) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setReal96(double value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setReal96(int offset, double value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setAlignedReal96(int index, double value) { + throw new UnsupportedOperationException("TODO"); + } + @Override public float getAlignedFloat(int index) { throw new UnsupportedOperationException("TODO"); diff --git a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtrPtr.java b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtrPtr.java index 4d0aeef467..0b504e9599 100644 --- a/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtrPtr.java +++ b/tools/gcc-bridge/runtime/src/main/java/org/renjin/gcc/runtime/RecordUnitPtrPtr.java @@ -187,6 +187,36 @@ public void setAlignedDouble(int index, double value) { throw new UnsupportedOperationException("TODO"); } + @Override + public double getReal96() { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getReal96(int offset) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public double getAlignedReal96(int index) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setReal96(double value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setReal96(int offset, double value) { + throw new UnsupportedOperationException("TODO"); + } + + @Override + public void setAlignedReal96(int index, double value) { + throw new UnsupportedOperationException("TODO"); + } + @Override public float getFloat() { throw new UnsupportedOperationException("TODO");