1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1987, 2000, 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* SunOS-4.1 */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* Unpack procedures for Sparc FPU simulator. */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include <sys/fpu/fpu_simulator.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/fpu/globals.h> 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate static void 35*7c478bd9Sstevel@tonic-gate unpackint32( 36*7c478bd9Sstevel@tonic-gate unpacked *pu, /* unpacked result */ 37*7c478bd9Sstevel@tonic-gate int32_t x) /* packed int32_t */ 38*7c478bd9Sstevel@tonic-gate { 39*7c478bd9Sstevel@tonic-gate uint_t ux; 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate pu->sticky = pu->rounded = 0; 42*7c478bd9Sstevel@tonic-gate if (x == 0) { 43*7c478bd9Sstevel@tonic-gate pu->sign = 0; 44*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_zero; 45*7c478bd9Sstevel@tonic-gate } else { 46*7c478bd9Sstevel@tonic-gate (*pu).sign = x < 0; 47*7c478bd9Sstevel@tonic-gate (*pu).fpclass = fp_normal; 48*7c478bd9Sstevel@tonic-gate (*pu).exponent = INTEGER_BIAS; 49*7c478bd9Sstevel@tonic-gate if (x < 0) ux = -x; else ux = x; 50*7c478bd9Sstevel@tonic-gate (*pu).significand[0] = ux>>15; 51*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = (ux&0x7fff)<<17; 52*7c478bd9Sstevel@tonic-gate (*pu).significand[2] = 0; 53*7c478bd9Sstevel@tonic-gate (*pu).significand[3] = 0; 54*7c478bd9Sstevel@tonic-gate fpu_normalize(pu); 55*7c478bd9Sstevel@tonic-gate } 56*7c478bd9Sstevel@tonic-gate } 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * Workaround for bug 4287443--- we have to convince the compiler 61*7c478bd9Sstevel@tonic-gate * that unpackint64 isn't a leaf routine. 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate static void 64*7c478bd9Sstevel@tonic-gate subroutine(void) 65*7c478bd9Sstevel@tonic-gate { 66*7c478bd9Sstevel@tonic-gate } 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate static void 69*7c478bd9Sstevel@tonic-gate unpackint64( 70*7c478bd9Sstevel@tonic-gate unpacked *pu, /* unpacked result */ 71*7c478bd9Sstevel@tonic-gate int64_t x) /* packed int64_t */ 72*7c478bd9Sstevel@tonic-gate { 73*7c478bd9Sstevel@tonic-gate union { 74*7c478bd9Sstevel@tonic-gate uint64_t ll; 75*7c478bd9Sstevel@tonic-gate uint32_t i[2]; 76*7c478bd9Sstevel@tonic-gate } ux; 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate subroutine(); 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate pu->sticky = pu->rounded = 0; 81*7c478bd9Sstevel@tonic-gate if (x == 0) { 82*7c478bd9Sstevel@tonic-gate pu->sign = 0; 83*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_zero; 84*7c478bd9Sstevel@tonic-gate } else { 85*7c478bd9Sstevel@tonic-gate (*pu).sign = x < 0; 86*7c478bd9Sstevel@tonic-gate (*pu).fpclass = fp_normal; 87*7c478bd9Sstevel@tonic-gate (*pu).exponent = LONGLONG_BIAS; 88*7c478bd9Sstevel@tonic-gate if (x < 0) ux.ll = -x; else ux.ll = x; 89*7c478bd9Sstevel@tonic-gate (*pu).significand[0] = ux.i[0]>>15; 90*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = (((ux.i[0]&0x7fff)<<17) | (ux.i[1]>>15)); 91*7c478bd9Sstevel@tonic-gate (*pu).significand[2] = (ux.i[1]&0x7fff)<<17; 92*7c478bd9Sstevel@tonic-gate (*pu).significand[3] = 0; 93*7c478bd9Sstevel@tonic-gate fpu_normalize(pu); 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate void 98*7c478bd9Sstevel@tonic-gate unpacksingle( 99*7c478bd9Sstevel@tonic-gate fp_simd_type *pfpsd, /* simulator data */ 100*7c478bd9Sstevel@tonic-gate unpacked *pu, /* unpacked result */ 101*7c478bd9Sstevel@tonic-gate single_type x) /* packed single */ 102*7c478bd9Sstevel@tonic-gate { 103*7c478bd9Sstevel@tonic-gate uint_t U; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate pu->sticky = pu->rounded = 0; 106*7c478bd9Sstevel@tonic-gate U = x.significand; 107*7c478bd9Sstevel@tonic-gate (*pu).sign = x.sign; 108*7c478bd9Sstevel@tonic-gate pu->significand[1] = 0; 109*7c478bd9Sstevel@tonic-gate pu->significand[2] = 0; 110*7c478bd9Sstevel@tonic-gate pu->significand[3] = 0; 111*7c478bd9Sstevel@tonic-gate if (x.exponent == 0) { /* zero or sub */ 112*7c478bd9Sstevel@tonic-gate if (x.significand == 0) { /* zero */ 113*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_zero; 114*7c478bd9Sstevel@tonic-gate return; 115*7c478bd9Sstevel@tonic-gate } else { /* subnormal */ 116*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_normal; 117*7c478bd9Sstevel@tonic-gate pu->exponent = -SINGLE_BIAS-6; 118*7c478bd9Sstevel@tonic-gate pu->significand[0] = U; 119*7c478bd9Sstevel@tonic-gate fpu_normalize(pu); 120*7c478bd9Sstevel@tonic-gate return; 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate } else if (x.exponent == 0xff) { /* inf or nan */ 123*7c478bd9Sstevel@tonic-gate if (x.significand == 0) { /* inf */ 124*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_infinity; 125*7c478bd9Sstevel@tonic-gate return; 126*7c478bd9Sstevel@tonic-gate } else { /* nan */ 127*7c478bd9Sstevel@tonic-gate if ((U & 0x400000) != 0) { /* quiet */ 128*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_quiet; 129*7c478bd9Sstevel@tonic-gate } else { /* signaling */ 130*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_signaling; 131*7c478bd9Sstevel@tonic-gate fpu_set_exception(pfpsd, fp_invalid); 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate pu->significand[0] = 0x18000 | (U >> 7); 134*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = ((U&0x7f)<<25); 135*7c478bd9Sstevel@tonic-gate return; 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate (*pu).exponent = x.exponent - SINGLE_BIAS; 139*7c478bd9Sstevel@tonic-gate (*pu).fpclass = fp_normal; 140*7c478bd9Sstevel@tonic-gate (*pu).significand[0] = 0x10000|(U>>7); 141*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = ((U&0x7f)<<25); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate void 145*7c478bd9Sstevel@tonic-gate unpackdouble( 146*7c478bd9Sstevel@tonic-gate fp_simd_type *pfpsd, /* simulator data */ 147*7c478bd9Sstevel@tonic-gate unpacked *pu, /* unpacked result */ 148*7c478bd9Sstevel@tonic-gate double_type x, /* packed double, sign/exponent/upper 20 bits */ 149*7c478bd9Sstevel@tonic-gate uint_t y) /* and the lower 32 bits of the significand */ 150*7c478bd9Sstevel@tonic-gate { 151*7c478bd9Sstevel@tonic-gate uint_t U; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate pu->sticky = pu->rounded = 0; 154*7c478bd9Sstevel@tonic-gate U = x.significand; 155*7c478bd9Sstevel@tonic-gate (*pu).sign = x.sign; 156*7c478bd9Sstevel@tonic-gate pu->significand[1] = y; 157*7c478bd9Sstevel@tonic-gate pu->significand[2] = 0; 158*7c478bd9Sstevel@tonic-gate pu->significand[3] = 0; 159*7c478bd9Sstevel@tonic-gate if (x.exponent == 0) { /* zero or sub */ 160*7c478bd9Sstevel@tonic-gate if ((x.significand == 0) && (y == 0)) { /* zero */ 161*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_zero; 162*7c478bd9Sstevel@tonic-gate return; 163*7c478bd9Sstevel@tonic-gate } else { /* subnormal */ 164*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_normal; 165*7c478bd9Sstevel@tonic-gate pu->exponent = -DOUBLE_BIAS-3; 166*7c478bd9Sstevel@tonic-gate pu->significand[0] = U; 167*7c478bd9Sstevel@tonic-gate fpu_normalize(pu); 168*7c478bd9Sstevel@tonic-gate return; 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate } else if (x.exponent == 0x7ff) { /* inf or nan */ 171*7c478bd9Sstevel@tonic-gate if ((U|y) == 0) { /* inf */ 172*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_infinity; 173*7c478bd9Sstevel@tonic-gate return; 174*7c478bd9Sstevel@tonic-gate } else { /* nan */ 175*7c478bd9Sstevel@tonic-gate if ((U & 0x80000) != 0) { /* quiet */ 176*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_quiet; 177*7c478bd9Sstevel@tonic-gate } else { /* signaling */ 178*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_signaling; 179*7c478bd9Sstevel@tonic-gate fpu_set_exception(pfpsd, fp_invalid); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate pu->significand[0] = 0x18000 | (U >> 4); 182*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = ((U&0xf)<<28)|(y>>4); 183*7c478bd9Sstevel@tonic-gate (*pu).significand[2] = ((y&0xf)<<28); 184*7c478bd9Sstevel@tonic-gate return; 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate (*pu).exponent = x.exponent - DOUBLE_BIAS; 188*7c478bd9Sstevel@tonic-gate (*pu).fpclass = fp_normal; 189*7c478bd9Sstevel@tonic-gate (*pu).significand[0] = 0x10000|(U>>4); 190*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = ((U&0xf)<<28)|(y>>4); 191*7c478bd9Sstevel@tonic-gate (*pu).significand[2] = ((y&0xf)<<28); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate static void 195*7c478bd9Sstevel@tonic-gate unpackextended( 196*7c478bd9Sstevel@tonic-gate fp_simd_type *pfpsd, /* simulator data */ 197*7c478bd9Sstevel@tonic-gate unpacked *pu, /* unpacked result */ 198*7c478bd9Sstevel@tonic-gate extended_type x, /* packed extended, sign/exponent/16 bits */ 199*7c478bd9Sstevel@tonic-gate uint32_t y, /* 2nd word of extended significand */ 200*7c478bd9Sstevel@tonic-gate uint32_t z, /* 3rd word of extended significand */ 201*7c478bd9Sstevel@tonic-gate uint32_t w) /* 4th word of extended significand */ 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate uint_t U; 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate pu->sticky = pu->rounded = 0; 206*7c478bd9Sstevel@tonic-gate U = x.significand; 207*7c478bd9Sstevel@tonic-gate (*pu).sign = x.sign; 208*7c478bd9Sstevel@tonic-gate (*pu).fpclass = fp_normal; 209*7c478bd9Sstevel@tonic-gate (*pu).exponent = x.exponent - EXTENDED_BIAS; 210*7c478bd9Sstevel@tonic-gate (*pu).significand[0] = (x.exponent == 0) ? U : 0x10000|U; 211*7c478bd9Sstevel@tonic-gate (*pu).significand[1] = y; 212*7c478bd9Sstevel@tonic-gate (*pu).significand[2] = z; 213*7c478bd9Sstevel@tonic-gate (*pu).significand[3] = w; 214*7c478bd9Sstevel@tonic-gate if (x.exponent < 0x7fff) { /* zero, normal, or subnormal */ 215*7c478bd9Sstevel@tonic-gate if ((z|y|w|pu->significand[0]) == 0) { /* zero */ 216*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_zero; 217*7c478bd9Sstevel@tonic-gate return; 218*7c478bd9Sstevel@tonic-gate } else { /* normal or subnormal */ 219*7c478bd9Sstevel@tonic-gate if (x.exponent == 0) { 220*7c478bd9Sstevel@tonic-gate fpu_normalize(pu); 221*7c478bd9Sstevel@tonic-gate pu->exponent += 1; 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate return; 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate } else { /* inf or nan */ 226*7c478bd9Sstevel@tonic-gate if ((U|z|y|w) == 0) { /* inf */ 227*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_infinity; 228*7c478bd9Sstevel@tonic-gate return; 229*7c478bd9Sstevel@tonic-gate } else { /* nan */ 230*7c478bd9Sstevel@tonic-gate if ((U & 0x00008000) != 0) { /* quiet */ 231*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_quiet; 232*7c478bd9Sstevel@tonic-gate } else { /* signaling */ 233*7c478bd9Sstevel@tonic-gate pu->fpclass = fp_signaling; 234*7c478bd9Sstevel@tonic-gate fpu_set_exception(pfpsd, fp_invalid); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate pu->significand[0] |= 0x8000; /* make quiet */ 237*7c478bd9Sstevel@tonic-gate return; 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate void 243*7c478bd9Sstevel@tonic-gate _fp_unpack( 244*7c478bd9Sstevel@tonic-gate fp_simd_type *pfpsd, /* simulator data */ 245*7c478bd9Sstevel@tonic-gate unpacked *pu, /* unpacked result */ 246*7c478bd9Sstevel@tonic-gate uint_t n, /* register where data starts */ 247*7c478bd9Sstevel@tonic-gate enum fp_op_type dtype) /* type of datum */ 248*7c478bd9Sstevel@tonic-gate { 249*7c478bd9Sstevel@tonic-gate freg_type f; 250*7c478bd9Sstevel@tonic-gate union { 251*7c478bd9Sstevel@tonic-gate uint32_t y[4]; 252*7c478bd9Sstevel@tonic-gate uint64_t ll[2]; 253*7c478bd9Sstevel@tonic-gate freg_type f; 254*7c478bd9Sstevel@tonic-gate } fp; 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate switch (dtype) { 257*7c478bd9Sstevel@tonic-gate case fp_op_int32: 258*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_freg(&f, n, pfpsd); 259*7c478bd9Sstevel@tonic-gate unpackint32(pu, f.int32_reg); 260*7c478bd9Sstevel@tonic-gate break; 261*7c478bd9Sstevel@tonic-gate case fp_op_int64: 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate if ((n & 0x1) == 1) /* fix register encoding */ 264*7c478bd9Sstevel@tonic-gate n = (n & 0x1e) | 0x20; 265*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_dreg(&fp.ll[0], DOUBLE(n), pfpsd); 266*7c478bd9Sstevel@tonic-gate unpackint64(pu, fp.f.int64_reg); 267*7c478bd9Sstevel@tonic-gate break; 268*7c478bd9Sstevel@tonic-gate case fp_op_single: 269*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_freg(&f, n, pfpsd); 270*7c478bd9Sstevel@tonic-gate unpacksingle(pfpsd, pu, f.single_reg); 271*7c478bd9Sstevel@tonic-gate break; 272*7c478bd9Sstevel@tonic-gate case fp_op_double: 273*7c478bd9Sstevel@tonic-gate if ((n & 0x1) == 1) /* fix register encoding */ 274*7c478bd9Sstevel@tonic-gate n = (n & 0x1e) | 0x20; 275*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_dreg(&fp.ll[0], DOUBLE(n), pfpsd); 276*7c478bd9Sstevel@tonic-gate unpackdouble(pfpsd, pu, fp.f.double_reg, fp.y[1]); 277*7c478bd9Sstevel@tonic-gate break; 278*7c478bd9Sstevel@tonic-gate case fp_op_extended: 279*7c478bd9Sstevel@tonic-gate if ((n & 0x1) == 1) /* fix register encoding */ 280*7c478bd9Sstevel@tonic-gate n = (n & 0x1e) | 0x20; 281*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_dreg(&fp.ll[0], QUAD_E(n), pfpsd); 282*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_dreg(&fp.ll[1], QUAD_F(n), pfpsd); 283*7c478bd9Sstevel@tonic-gate unpackextended(pfpsd, pu, fp.f.extended_reg, fp.y[1], 284*7c478bd9Sstevel@tonic-gate fp.y[2], fp.y[3]); 285*7c478bd9Sstevel@tonic-gate break; 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate void 290*7c478bd9Sstevel@tonic-gate _fp_unpack_word( 291*7c478bd9Sstevel@tonic-gate fp_simd_type *pfpsd, /* simulator data */ 292*7c478bd9Sstevel@tonic-gate uint32_t *pu, /* unpacked result */ 293*7c478bd9Sstevel@tonic-gate uint_t n) /* register where data starts */ 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_freg(pu, n, pfpsd); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate void 299*7c478bd9Sstevel@tonic-gate _fp_unpack_extword( 300*7c478bd9Sstevel@tonic-gate fp_simd_type *pfpsd, /* simulator data */ 301*7c478bd9Sstevel@tonic-gate uint64_t *pu, /* unpacked result */ 302*7c478bd9Sstevel@tonic-gate uint_t n) /* register where data starts */ 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate if ((n & 0x1) == 1) /* fix register encoding */ 305*7c478bd9Sstevel@tonic-gate n = (n & 0x1e) | 0x20; 306*7c478bd9Sstevel@tonic-gate pfpsd->fp_current_read_dreg(pu, DOUBLE(n), pfpsd); 307*7c478bd9Sstevel@tonic-gate } 308