Commit | Line | Data |
---|---|---|
53047a66 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: Matthew Khouzam - Initial API and implementation | |
10 | *******************************************************************************/ | |
11 | ||
12 | package org.eclipse.linuxtools.ctf.core.event.types; | |
13 | ||
486efb2e | 14 | import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; |
53047a66 | 15 | |
9ac2eb62 | 16 | /** |
d37aaa7f | 17 | * A CTF float definition. |
486efb2e | 18 | * |
d37aaa7f FC |
19 | * The definition of a floating point basic data type. It will take the data |
20 | * from a trace and store it (and make it fit) as a double. | |
9ac2eb62 | 21 | * |
d37aaa7f FC |
22 | * @version 1.0 |
23 | * @author Matthew Khouzam | |
24 | * @author Simon Marchi | |
9ac2eb62 | 25 | */ |
53047a66 MK |
26 | public class FloatDefinition extends Definition { |
27 | // ------------------------------------------------------------------------ | |
28 | // Attributes | |
29 | // ------------------------------------------------------------------------ | |
30 | ||
31 | private final FloatDeclaration declaration; | |
32 | private double value; | |
33 | ||
34 | // ------------------------------------------------------------------------ | |
a511da0d | 35 | // Constructors |
53047a66 MK |
36 | // ------------------------------------------------------------------------ |
37 | ||
9ac2eb62 MK |
38 | /** |
39 | * Constructor | |
40 | * | |
41 | * @param declaration | |
42 | * the parent declaration | |
43 | * @param definitionScope | |
44 | * the parent scope | |
45 | * @param fieldName | |
46 | * the field name | |
47 | */ | |
53047a66 MK |
48 | public FloatDefinition(FloatDeclaration declaration, |
49 | IDefinitionScope definitionScope, String fieldName) { | |
50 | super(definitionScope, fieldName); | |
51 | this.declaration = declaration; | |
52 | } | |
07002e0a | 53 | |
53047a66 | 54 | // ------------------------------------------------------------------------ |
a511da0d | 55 | // Getters/Setters/Predicates |
53047a66 MK |
56 | // ------------------------------------------------------------------------ |
57 | ||
9ac2eb62 | 58 | /** |
a511da0d | 59 | * The value of a float stored, fit into a double. This should be extended |
9ac2eb62 MK |
60 | * for exotic floats if this is necessary. |
61 | * | |
62 | * @return the value of the float field fit into a double. | |
63 | */ | |
53047a66 MK |
64 | public double getValue() { |
65 | return value; | |
66 | } | |
67 | ||
9ac2eb62 MK |
68 | /** |
69 | * Sets the value of the float | |
70 | * | |
71 | * @param val | |
72 | * the value of the float | |
73 | */ | |
53047a66 MK |
74 | public void setValue(double val) { |
75 | value = val; | |
76 | } | |
77 | ||
9ac2eb62 | 78 | @Override |
53047a66 MK |
79 | public FloatDeclaration getDeclaration() { |
80 | return declaration; | |
81 | } | |
82 | ||
83 | // ------------------------------------------------------------------------ | |
84 | // Operations | |
85 | // ------------------------------------------------------------------------ | |
86 | ||
53047a66 MK |
87 | @Override |
88 | public void read(BitBuffer input) { | |
9722444c | 89 | /* Offset the buffer position wrt the current alignment */ |
d6205f97 | 90 | alignRead(input, this.declaration); |
9722444c AM |
91 | final int exp = declaration.getExponent(); |
92 | final int mant = declaration.getMantissa(); | |
93 | ||
07002e0a MK |
94 | if ((exp + mant) == 32) { |
95 | value = readRawFloat32(input, mant, exp); | |
96 | } else if ((exp + mant) == 64) { | |
97 | value = readRawFloat64(input, mant, exp); | |
98 | } else { | |
53047a66 MK |
99 | value = Double.NaN; |
100 | } | |
101 | } | |
102 | ||
07002e0a MK |
103 | private static double readRawFloat64(BitBuffer input, final int manBits, |
104 | final int expBits) { | |
105 | long low = input.getInt(32, false); | |
106 | low = low & 0x00000000FFFFFFFFL; | |
107 | long high = input.getInt(32, false); | |
108 | high = high & 0x00000000FFFFFFFFL; | |
109 | long temp = (high << 32) | low; | |
110 | return createFloat(temp, manBits - 1, expBits); | |
53047a66 MK |
111 | } |
112 | ||
113 | /** | |
114 | * @param rawValue | |
115 | * @param manBits | |
116 | * @param expBits | |
117 | */ | |
07002e0a MK |
118 | private static double createFloat(long rawValue, final int manBits, |
119 | final int expBits) { | |
fd74e6c1 MK |
120 | long manShift = 1L << (manBits); |
121 | long manMask = manShift - 1; | |
122 | long expMask = (1L << expBits) - 1; | |
123 | ||
07002e0a | 124 | int exp = (int) ((rawValue >> (manBits)) & expMask) + 1; |
fd74e6c1 | 125 | long man = (rawValue & manMask); |
d6205f97 MK |
126 | final int offsetExponent = exp - (1 << (expBits - 1)); |
127 | double expPow = Math.pow(2.0, offsetExponent); | |
fd74e6c1 MK |
128 | double ret = man * 1.0f; |
129 | ret /= manShift; | |
130 | ret += 1.0; | |
131 | ret *= expPow; | |
132 | return ret; | |
53047a66 MK |
133 | } |
134 | ||
fd74e6c1 | 135 | private static double readRawFloat32(BitBuffer input, final int manBits, |
07002e0a | 136 | final int expBits) { |
53047a66 | 137 | long temp = input.getInt(32, false); |
07002e0a | 138 | return createFloat(temp, manBits - 1, expBits); |
53047a66 MK |
139 | } |
140 | ||
141 | @Override | |
142 | public String toString() { | |
143 | return String.valueOf(value); | |
144 | } | |
145 | } |