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