fpu_fsr_test.c revision 60c45ed01d4f99571d468c42f609d11a099fab1e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc.
* All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <fp.h>
#include <externs.h>
#include <fps_ereport.h>
/* Traps enabled or disabled */
#define T_ENABLED 1
#define T_DISABLED 0
static int test_ieee754_exc_fields(int trapStatus,
struct fps_test_ereport *report);
/*
* Test data for testing the IEEE 754 exceptions.
* The first 5 entries are for the 5 FP exception fields of the FSR
*/
/*
* a_msw, a_lsw, b_msw, b_lsw, instr, fsr_tem0..., fsr_tem1...,
* ecode
*/
/* More IEEE 754 exceptions */
/* (+inf) + (-inf) */
/* (0) * (+inf) */
/* (0) * (-inf) */
/* (+inf) / (+inf) */
/* (+inf) / (-inf) */
/* sqrt(-1) */
{00, 00, 000, 000, 0000, 0x0, 0x0, 0x0}};
/* Data used in test_fccn() */
/* No. of fccn fields in the FSR */
#define N_FCCN 4
/*
* No. of bits to shift a fcc field to the right so that its value occupies
* the least significant bits
*/
#define FSR_FCC0_SRL_N 10
#define FSR_FCC1_SRL_N 32
#define FSR_FCC2_SRL_N 34
#define FSR_FCC3_SRL_N 36
{
};
static unsigned int fccShifts[] =
{
};
/*
* Data structure for the fccn test data. We are using only single-precision
* comparisions
*/
typedef struct {
char *testId;
unsigned int val1; /* Operand 1 */
unsigned int val2; /* Operand 2 */
/* The value of the fcc field after the FP operation */
unsigned int fccVal;
}FccData;
{
{"test-0", 0xc0980000, 0xc0980000, 0}, /* -ve = -ve */
{"test-1", 0x40980000, 0x40980000, 0}, /* +ve = +ve */
{"test-2", 0xc0980000, 0x40980000, 1}, /* -ve < +ve */
{"test-3", 0xc0980000, 0xc094cccd, 1}, /* -ve < -ve */
{"test-4", 0x40980000, 0x40983958, 1}, /* +ve < +ve */
{"test-5", 0x40980000, 0xc0980000, 2}, /* +ve > -ve */
{"test-6", 0x40983958, 0x40980000, 2}, /* +ve > +ve */
{"test-7", 0xc094cccd, 0xc0980000, 2}, /* -ve > -ve */
};
/* Data used in test_rounding() */
#define FOUR_SP 0x40800000U
#define THREE_SP 0x40400000U
#define FOUR_DP_MSW 0x40100000U
#define FOUR_DP_LSW 0x00000000U
#define THREE_DP_MSW 0x40080000U
#define THREE_DP_LSW 0x00000000U
#define FSR_RD_MASK_Z 0xFFFFFFFF3FFFFFFFUL
/* No. of IEEE 754 rounding modes */
#define N_RD_MODES 4
/* Data structure for the rounding test data */
typedef struct {
char *test_id;
unsigned int operand1_msw;
unsigned int operand1_lsw;
unsigned int operand2_msw;
unsigned int operand2_lsw;
unsigned int operation;
} RoundingData;
/* Strings for rounding modes */
static char *rndModes[] =
{
"Round to Nearest",
"Round to Zero",
"Round to +infinity",
"Round to -infinity",
};
/* Rounding test data */
static RoundingData r_data[] =
{
/* 4/3 SP */
{"Test-0",
0x3faaaaab,
0x3faaaaaa,
0x3faaaaab,
0x3faaaaaa},
/* 4/3 DP */
{"Test-1",
0x3ff5555555555555,
0x3ff5555555555555,
0x3ff5555555555556,
0x3ff5555555555555},
{"Test-2",
0xc0600018,
0xc1700009,
0xc1940008,
0xc1940007,
0xc1940007,
0xc1940008},
{"Test-3",
0x880c0000,
0x00000018,
0x882e0000,
0x00000009,
0x8832800000000008,
0x8832800000000007,
0x8832800000000007,
0x8832800000000008},
/* 4/3 (DP) and convert to SP */
{"Test-4",
0x3faaaaab,
0x3faaaaaa,
0x3faaaaab,
0x3faaaaaa},
/*
* Convert a 64-bit *signed* integer to a single- precison FP number.
* The 64-bit signed number used here, 0x0x882e000000000009, is
* -0x77d1fffffffffff7 i.e -8633963435622662135.
*/
{"Test-5",
0x882e0000,
0x00000009,
0xdeefa400,
0xdeefa3ff,
0xdeefa3ff,
0xdeefa400}
};
/*
* fsr_test(struct fps_test_ereport *report) is the high level
* caller of the functions that test the different fields of
* the FSR. If an error is found, relevant data is stored in
* report.
*/
int
{
return (FPU_FOROFFLINE);
return (FPU_FOROFFLINE);
return (FPU_FOROFFLINE);
return (FPU_FOROFFLINE);
return (FPU_OK);
}
/*
* test_ieee754_exc_fields(int trapStatus,
* struct fps_test_ereport *report)tests the FSR.cexc,
* and FSR.aexc fields. It can operate in two modes: traps
* enabled and traps disabled.
*
* In the T_DISABLED (FSR.TEM=0) mode, it checks if the
* FSR.cexc and FSR.aexc fields have been set correctly.
*
* In the T_ENABLED mode, it check if the
* appropriate trap has been raised and the FSR.cexc field has the correct
* value.
*
* If an error is found, relevant data is stored in report.
*/
static int
{
char err_data[MAX_INFO_SIZE];
int i;
int rval;
unsigned long alsw;
unsigned long amsw;
unsigned long blsw;
unsigned long bmsw;
unsigned long exc_bits;
unsigned long operation;
if (trapStatus == T_DISABLED) {
} else {
t_fsr |= 0x000000000F800000;
}
if (trapStatus == T_DISABLED)
else
result_fsr = 0;
fsr_at_trap = 0;
switch (operation) {
case op_add_sp:
break;
case op_add_dp:
break;
case op_div_sp:
break;
case op_div_dp:
break;
case op_mul_sp:
break;
case op_mul_dp:
break;
case op_fsqrts:
break;
case op_fsqrtd:
| alsw);
break;
default:
break;
}
if (trapStatus == T_ENABLED) {
if (!trap_flag) {
} else {
observed = 1;
expected = 0;
"test: %d", i);
}
}
"test: %d, trapStatus: %d", i, trapStatus);
}
}
return (rval);
}
/*
* test_fccn(struct fps_test_ereport *report)
* test the fcc0, fcc1, fcc2, and fcc3 fields of the FSR. Single-
* precision comparision operations are done using the test data given
* in fccData[], and the resultant value in the fccN field is compared
* against the value in fccData. Each test data is used with all the
* four fcc fields.
*
* If an error is found, relevant data is stored in report.
*/
static int
{
char err_data[MAX_INFO_SIZE];
int fcc;
int i;
int rval;
unsigned int shiftBits;
#ifdef __lint
#else
unsigned int des_fcc;
unsigned int res_fcc;
#endif
for (i = 0; i < N_FCCDATA; i++) {
>> shiftBits);
"FSR.fcc: %d, FCC ID: %s"
"\nExpected: %lld"
"\nObserved: %lld",
res_fcc);
continue;
}
}
}
return (rval);
}
/*
* test_rounding(struct fps_test_ereport *report)
* tests the 4 IEEE 754 rounding modes.
* If an error is found, relevant data is stored
* in report.
*/
static int
{
char err_data[MAX_INFO_SIZE];
int i;
int rval;
for (i = 0; i < R_DATA_N; i++) {
if (rd == 0)
else if (rd == 1)
else if (rd == 2)
else if (rd == 3)
case op_add_sp:
r_data[i].operand2_msw);
break;
case op_add_dp:
oprnd1 =
oprnd2 =
break;
case op_div_sp:
r_data[i].operand2_msw);
break;
case op_div_dp:
oprnd1 =
oprnd2 =
break;
case op_div_dp_c2sp:
oprnd1 =
oprnd2 =
break;
case op_fxtos:
oprnd =
break;
default:
break;
}
"FSR.RD: %d, %s, TestID: %s"
"\nExpected: %lld\nObserved: %lld",
}
}
}
return (rval);
}