001 // This file is part of the program FRYSK. 002 // 003 // Copyright 2007, Red Hat Inc. 004 // 005 // FRYSK is free software; you can redistribute it and/or modify it 006 // under the terms of the GNU General Public License as published by 007 // the Free Software Foundation; version 2 of the License. 008 // 009 // FRYSK is distributed in the hope that it will be useful, but 010 // WITHOUT ANY WARRANTY; without even the implied warranty of 011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 // General Public License for more details. 013 // 014 // You should have received a copy of the GNU General Public License 015 // along with FRYSK; if not, write to the Free Software Foundation, 016 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 017 // 018 // In addition, as a special exception, Red Hat, Inc. gives You the 019 // additional right to link the code of FRYSK with code not covered 020 // under the GNU General Public License ("Non-GPL Code") and to 021 // distribute linked combinations including the two, subject to the 022 // limitations in this paragraph. Non-GPL Code permitted under this 023 // exception must only link to the code of FRYSK through those well 024 // defined interfaces identified in the file named EXCEPTION found in 025 // the source code files (the "Approved Interfaces"). The files of 026 // Non-GPL Code may instantiate templates or use macros or inline 027 // functions from the Approved Interfaces without causing the 028 // resulting work to be covered by the GNU General Public 029 // License. Only Red Hat, Inc. may make changes or additions to the 030 // list of Approved Interfaces. You must obey the GNU General Public 031 // License in all respects for all of the FRYSK code and other code 032 // used in conjunction with FRYSK except the Non-GPL Code covered by 033 // this exception. If you modify this file, you may extend this 034 // exception to your version of the file, but you are not obligated to 035 // do so. If you do not wish to provide this exception without 036 // modification, you must delete this exception statement from your 037 // version and license this file solely under the GPL without 038 // exception. 039 040 package frysk.value; 041 042 import inua.eio.ByteOrder; 043 import inua.eio.ByteBuffer; 044 import java.io.PrintWriter; 045 import java.math.BigInteger; 046 047 /** 048 * Type for a floating-point value. 049 */ 050 051 public class FloatingPointType 052 extends ArithmeticType 053 { 054 055 private FloatingPointFormat format; 056 057 public FloatingPointType(String name, ByteOrder order, int size) { 058 super(name, order, size); 059 060 switch (size) { 061 case 4: format = FloatingPoint854Format.IEEE32; 062 break; 063 case 8: format = FloatingPoint854Format.IEEE64; 064 break; 065 case 16:format = FloatingPoint854Format.IEEE128; 066 break; 067 case 10:format = FloatingPoint854Format.IEEE80; 068 break; 069 case 12:format = FloatingPoint854Format.IEEE96; 070 break; 071 default:format = FloatingPoint854Format.IEEE64; 072 break; 073 } 074 } 075 076 public void toPrint(PrintWriter writer, Location location, 077 ByteBuffer memory, Format format, int indent) { 078 // double-dispatch. 079 format.print(writer, location, this); 080 } 081 082 /** 083 * Prints value as a hexadecimal float constant. 084 * eg. double value 9.0 --> 0x1.2p+0 085 */ 086 public void printAsHexConstant (PrintWriter writer, Location loc) { 087 byte[] bytes = loc.get(order()); 088 FloatingPoint854Format f = (FloatingPoint854Format)format; 089 writer.print(f.getSign(bytes)==0? "":"-"); 090 writer.print("0x"); 091 writer.print(f.getIntegralOfMantissa(bytes)); 092 writer.print('.'); 093 writer.print(f.getFraction(bytes).toString(16)); 094 writer.print('p'); 095 writer.print(f.getBiasedExponent(bytes).intValue() 096 - f.getMaxEValue().intValue()/2); 097 } 098 099 /** 100 * Return the raw bytes as an unsigned integer. 101 */ 102 BigInteger getBigInteger(Location location) { 103 return new BigInteger(1, location.get(order())); 104 } 105 106 void putBigInteger(Location location, BigInteger val) { 107 location.put(order(), val.toByteArray(), 0); 108 } 109 110 void putBigFloatingPoint(Location location, BigFloatingPoint val) { 111 location.put(order(), this.format.pack(val, this.getSize()), 0); 112 } 113 114 BigFloatingPoint getBigFloatingPoint(Location location) { 115 return format.unpack(location.get(order())); 116 } 117 118 BigFloatingPoint bigFloatingPointValue(Location location) { 119 return getBigFloatingPoint(location); 120 } 121 122 BigInteger bigIntegerValue (Location location) { 123 return getBigFloatingPoint(location).bigIntegerValue(); 124 } 125 126 void assign(Location location, Value v) { 127 BigFloatingPoint f = ((FloatingPointType)v.getType()).bigFloatingPointValue(v.getLocation()); 128 location.put(order(), format.pack(f, getSize()), 0); 129 } 130 131 /* getALUs are double dispatch functions to determine 132 * the ArithmeticUnit for an operation between two types. 133 */ 134 public ArithmeticUnit getALU(Type type, int wordSize) { 135 return type.getALU(this, wordSize); 136 } 137 public ArithmeticUnit getALU(IntegerType type, int wordSize) { 138 return new FloatingPointUnit(this, wordSize); 139 } 140 public ArithmeticUnit getALU(FloatingPointType type, int wordSize) { 141 return new FloatingPointUnit(this, type, wordSize); 142 } 143 public ArithmeticUnit getALU(PointerType type, int wordSize) { 144 throw new RuntimeException("Invalid Pointer Arithmetic"); 145 } 146 // Use for unary operations. 147 public ArithmeticUnit getALU(int wordSize) { 148 return new FloatingPointUnit(this, wordSize); 149 } 150 }