1(* 2 Title: Standard Basis Library: Pack Real32 structures for 64-bit platforms 3 Author: David Matthews 4 Copyright David Matthews 2021 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 Licence version 2.1 as published by the Free Software Foundation. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public Licence for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18*) 19 20(* On 64-bit platforms Real32.real values are held as tagged values 21 with the floating point value in the high-order 32-bits. *) 22 23local 24 val r32AsWord: Real32.real -> word = RunCall.unsafeCast 25 and wordAsR32: word -> Real32.real = RunCall.unsafeCast 26 27 infix << >> 28 infix orb 29 val op orb = Word.orb 30 and op << = Word.<< 31 and op >> = Word.>> 32 33 val wordToW8 = Word8.fromLarge o Word.toLarge 34 and w8ToWord = Word.fromLarge o Word8.toLarge 35 36 (* Word values are already shifted by one bit so the 37 actual shifts are 31, 39, 47 and 55 bits. *) 38 val shift0 = Word.fromInt Word.wordSize - 0w32 39 and shift1 = Word.fromInt Word.wordSize - 0w24 40 and shift2 = Word.fromInt Word.wordSize - 0w16 41 and shift3 = Word.fromInt Word.wordSize - 0w08 42in 43 44 structure PackReal32Little: PACK_REAL = 45 struct 46 type real = Real32.real 47 val bytesPerElem = 4 48 val isBigEndian = false 49 50 fun toBytes r = 51 let 52 val w: word = r32AsWord r 53 in 54 Word8Vector.fromList[wordToW8(w >> shift0), wordToW8(w >> shift1), 55 wordToW8(w >> shift2), wordToW8(w >> shift3)] 56 end 57 58 fun subVec(v, i) = 59 let 60 val iW = i * bytesPerElem 61 in 62 wordAsR32((w8ToWord(Word8Vector.sub(v, iW)) << shift0) orb 63 (w8ToWord(Word8Vector.sub(v, iW+1)) << shift1) orb 64 (w8ToWord(Word8Vector.sub(v, iW+2)) << shift2) orb 65 (w8ToWord(Word8Vector.sub(v, iW+3)) << shift3)) 66 end 67 68 fun fromBytes v = subVec(v, 0) 69 70 fun subArr(v, i) = 71 let 72 val iW = i * bytesPerElem 73 in 74 wordAsR32((w8ToWord(Word8Array.sub(v, iW)) << shift0) orb 75 (w8ToWord(Word8Array.sub(v, iW+1)) << shift1) orb 76 (w8ToWord(Word8Array.sub(v, iW+2)) << shift2) orb 77 (w8ToWord(Word8Array.sub(v, iW+3)) << shift3)) 78 end 79 80 fun update(v, i, r) = 81 let 82 val w: word = r32AsWord r 83 open Word8Array 84 val iW = i * bytesPerElem 85 in 86 Word8Array.update(v, iW, wordToW8(w >> shift0)); 87 Word8Array.update(v, iW+1, wordToW8(w >> shift1)); 88 Word8Array.update(v, iW+2, wordToW8(w >> shift2)); 89 Word8Array.update(v, iW+3, wordToW8(w >> shift3)) 90 end 91 end 92 93 structure PackReal32Big: PACK_REAL = 94 struct 95 type real = Real32.real 96 val bytesPerElem = 4 97 val isBigEndian = false 98 99 fun toBytes r = 100 let 101 val w: word = r32AsWord r 102 in 103 Word8Vector.fromList[wordToW8(w >> shift3), wordToW8(w >> shift2), 104 wordToW8(w >> shift1), wordToW8(w >> shift0)] 105 end 106 107 fun subVec(v, i) = 108 let 109 val iW = i * bytesPerElem 110 in 111 wordAsR32((w8ToWord(Word8Vector.sub(v, iW)) << shift3) orb 112 (w8ToWord(Word8Vector.sub(v, iW+1)) << shift2) orb 113 (w8ToWord(Word8Vector.sub(v, iW+2)) << shift1) orb 114 (w8ToWord(Word8Vector.sub(v, iW+3)) << shift0)) 115 end 116 117 fun fromBytes v = subVec(v, 0) 118 119 fun subArr(v, i) = 120 let 121 val iW = i * bytesPerElem 122 in 123 wordAsR32((w8ToWord(Word8Array.sub(v, iW)) << shift3) orb 124 (w8ToWord(Word8Array.sub(v, iW+1)) << shift2) orb 125 (w8ToWord(Word8Array.sub(v, iW+2)) << shift1) orb 126 (w8ToWord(Word8Array.sub(v, iW+3)) << shift0)) 127 end 128 129 fun update(v, i, r) = 130 let 131 val w: word = r32AsWord r 132 open Word8Array 133 val iW = i * bytesPerElem 134 in 135 Word8Array.update(v, iW, wordToW8(w >> shift3)); 136 Word8Array.update(v, iW+1, wordToW8(w >> shift2)); 137 Word8Array.update(v, iW+2, wordToW8(w >> shift1)); 138 Word8Array.update(v, iW+3, wordToW8(w >> shift0)) 139 end 140 end 141 142end; 143