Merge remote-tracking branch 'origin/development' into development
[Mograsim.git] / net.mograsim.machine / src / net / mograsim / machine / isa / AsmFloatOperand.java
1 package net.mograsim.machine.isa;\r
2 \r
3 import java.math.BigDecimal;\r
4 import java.math.BigInteger;\r
5 \r
6 import net.mograsim.logic.core.types.Bit;\r
7 import net.mograsim.logic.core.types.BitVector;\r
8 import net.mograsim.logic.core.types.BitVector.BitVectorMutator;\r
9 import net.mograsim.machine.isa.types.AsmNumberFormatException;\r
10 \r
11 public class AsmFloatOperand implements AsmOperand\r
12 {\r
13         private final int size;\r
14         private final int mantissa;\r
15         private final int exponent;\r
16 \r
17         public AsmFloatOperand(int size)\r
18         {\r
19                 this.size = size;\r
20                 switch (size)\r
21                 {\r
22                 case 8:\r
23                         exponent = 4;\r
24                         mantissa = 3;\r
25                         break;\r
26                 case 16:\r
27                         exponent = 5;\r
28                         mantissa = 10;\r
29                         break;\r
30                 case 32:\r
31                         exponent = 8;\r
32                         mantissa = 23;\r
33                         break;\r
34                 case 64:\r
35                         exponent = 11;\r
36                         mantissa = 52;\r
37                         break;\r
38                 case 128:\r
39                         exponent = 15;\r
40                         mantissa = 112;\r
41                         break;\r
42                 default:\r
43                         if (size > 128 && size % 32 == 0)\r
44                         {\r
45                                 exponent = (int) Math.round(Math.log(size) / Math.log(2)) - 13;\r
46                                 mantissa = size - exponent - 1;\r
47                         } else\r
48                         {\r
49                                 throw new IllegalArgumentException("Illegal floating point size: " + size);\r
50                         }\r
51                 }\r
52         }\r
53 \r
54         public AsmFloatOperand(int exponent, int mantissa)\r
55         {\r
56                 if (exponent < 1 || mantissa < 1)\r
57                         throw new IllegalArgumentException("illegal floating point specification: e=" + exponent + ", m=" + mantissa);\r
58                 this.exponent = exponent;\r
59                 this.mantissa = mantissa;\r
60                 this.size = exponent + mantissa + 1;\r
61         }\r
62 \r
63         @Override\r
64         public int getSize()\r
65         {\r
66                 return size;\r
67         }\r
68 \r
69         @Override\r
70         public BitVector parse(String s) throws AsmNumberFormatException\r
71         {\r
72                 String cleaned = s.replace("_", "").toLowerCase();\r
73                 int len = cleaned.length();\r
74                 BigInteger res;\r
75                 try\r
76                 {\r
77                         return bigDecToBitVector(new BigDecimal(cleaned));\r
78                 }\r
79                 catch (NumberFormatException e)\r
80                 {\r
81                         throw new AsmNumberFormatException(e, "Error parsing %s: no valid float format", s);\r
82                 }\r
83         }\r
84 \r
85         BitVector bigDecToBitVector(BigDecimal bi) throws AsmNumberFormatException\r
86         {\r
87                 BigInteger raw = bi.unscaledValue();\r
88                 int mantLen = raw.bitLength();\r
89 //              bi.\r
90                 int bitLength = raw.bitLength() - (bi.signum() - 1) / 2;\r
91                 if (bitLength > size)\r
92                         throw new AsmNumberFormatException("Error parsing %s: bit count %d exceeds size %d", bi, bitLength, size);\r
93                 BitVectorMutator bvm = BitVectorMutator.ofLength(size);\r
94                 for (int i = 0; i < size; i++)\r
95                         bvm.setLSBit(i, Bit.of(raw.testBit(i)));\r
96                 return bvm.toBitVector();\r
97         }\r
98 }\r