📄 main.c
字号:
/*********************************************************************** * * main.c * * main() function for sample application ("yamon_fpu" application). * * ###################################################################### * * mips_start_of_legal_notice * * Copyright (c) 2002 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the Copyright Laws of the * United States of America. * * If this document is provided in source format (i.e., in a modifiable form * such as in FrameMaker or Microsoft Word format), then its use and * distribution is subject to a written agreement with MIPS Technologies, * Inc. ("MIPS Technologies"). UNDER NO CIRCUMSTANCES MAY A DOCUMENT * PROVIDED IN SOURCE FORMAT BE DISTRIBUTED TO A THIRD PARTY WITHOUT THE * EXPRESS WRITTEN CONSENT OF MIPS TECHNOLOGIES. * * This document contains information that is proprietary to MIPS * Technologies. Any copying, reproducing, modifying, or use of this * information (in whole or in part) which is not expressly permitted in * writing by MIPS Technologies or a contractually-authorized third party is * strictly prohibited. At a minimum, this information is protected under * unfair competition and copyright laws. Violations thereof may result in * criminal penalties and fines. * * MIPS Technologies or any contractually-authorized third party reserves * the right to change the information contained in this document to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this information, or * of any error of omission in such information. Any warranties, whether * express, statutory, implied or otherwise, including but not limited to * the implied warranties of merchantability or fitness for a particular * purpose, are excluded. Any license under patent rights or any other * intellectual property rights owned by MIPS Technologies or third parties * shall be conveyed by MIPS Technologies or any contractually-authorized * third party in a separate license agreement between the parties. * * The information contained in this document shall not be exported or * transferred for the purpose of reexporting in violation of any U.S. or * non-U.S. regulation, treaty, Executive Order, law, statute, amendment or * supplement thereto. * * The information contained in this document constitutes one or more of the * following: commercial computer software, commercial computer software * documentation or other commercial items. If the user of this information, * or any related documentation of any kind, including related technical * data or manuals, is an agency, department, or other entity of the United * States government ("Government"), the use, duplication, reproduction, * release, modification, disclosure, or transfer of this information, or * any related documentation of any kind, is restricted in accordance with * Federal Acquisition Regulation 12.212 for civilian agencies and Defense * Federal Acquisition Regulation Supplement 227.7202 for military agencies. * The use of this information by the Government is further restricted in * accordance with the terms of the license agreement(s) and/or applicable * contract terms and conditions covering this information from MIPS * * mips_end_of_legal_notice * * ************************************************************************//************************************************************************ * Include files ************************************************************************/#include <yamon_api.h>#include <stdio.h>/************************************************************************ * Definitions ************************************************************************/typedef union number_s { long l; float f;#if EL struct { unsigned mant:23; unsigned bexp:8; unsigned sign:1; } p;#endif#if EB struct { unsigned sign:1; unsigned bexp:8; unsigned mant:23; } p;#endif} t_number;#define puts YAMON_FUNC_PRINT /* This puts() will not append '\n' *//************************************************************************ * Public variables ************************************************************************//************************************************************************ * Static variables ************************************************************************//************************************************************************ * External function prototypes ************************************************************************/void my_add(float *result, float *arg1, float *arg2);void my_dadd(float *result, float *arg1, float *arg2);/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * strcpy * Description : * ------------- * Would normally be a library routine * ************************************************************************/staticchar *strcpy(char *dest, const char *src){ char *s = dest; while((*dest++ = *src++)) ; return s;}/************************************************************************ * * int2str * Description : * ------------- * Example of a simple int2str() conversion routine * ************************************************************************/staticchar *int2str(unsigned int i, char *buf, int prec){ unsigned int j; for (j = 1; i / j >= 10; j *= 10) prec--; while (--prec > 0) *buf++ = '0'; while (j) { *buf++ = i / j + '0'; i -= i / j * j; j /= 10; } *buf = '\0'; return buf;}/************************************************************************ * * lldiv * Description : * ------------- * Example of a lldiv routine that does not return remainder. * Actually, "dividend" ends up having the remainder's value. * ************************************************************************/staticunsigned long long lldiv(unsigned long long dividend, unsigned long long divisor){ int i, bit_count = 0; unsigned long long quotient; if (divisor == 0) return 0; while (divisor < dividend && (signed long long)divisor >= 0) { bit_count++; divisor <<= 1; } quotient = 0; for (i = 0; i <= bit_count; i++) { quotient <<= 1; if (divisor <= dividend) { dividend -= divisor; quotient |= 1; } divisor >>= 1; } return quotient;}/************************************************************************ * * f2str * Description : * ------------- * Example of a very basic float2str conversion routine. * ************************************************************************/staticchar * f2str(long f, char *argbuf){ unsigned long long l; unsigned int m1, m2; int e, be; t_number n; char *buf; n.l = f; buf = argbuf; /************************************ ** Boundary checks */ if (n.p.bexp == 255) { if (n.p.mant == 0) { if (n.p.sign) *buf++ = '-'; strcpy(buf, "inf"); } else if (n.p.mant & (1 << 22)) { strcpy(buf, "SNaN"); } else { strcpy(buf, "QNaN"); } return argbuf; } if (n.p.bexp == 0 && n.p.mant == 0) { if (n.p.sign) *buf++ = '-'; strcpy(buf, "0.000000e+00"); return argbuf; } /************************************ ** Convert binary exponent to decimal ** while keeping mantissa aligned */ e = 18; if (n.p.bexp == 0) { /* Denormalized number */ strcpy(buf, "den "); buf += 4; be = -126; l = n.p.mant; while (l < (1 << 23)) { be--; l <<= 1; } } else { be = n.p.bexp - 127; l = n.p.mant | 1 << 23; } if (be >= 23) { while (be-- > 23) { l <<= 1; if ((signed long long)l < 0) { l = lldiv(l, 10); e++; } } } else { while (be++ < 23) { while (l < (unsigned long long)1E18) { l *= 10; e--; } l >>= 1; } } while (l < (unsigned long long)1E18) { l *= 10; e--; } /************************************ ** round and "shift" 10**12 left */ l += (unsigned long long)5E11; m2 = lldiv(l, (unsigned long long)1E12); if (m2 >= (unsigned int)1E7) { /* rounded from 9,999,999.(7) to 10,000,000.(2) - align properly */ m2 = (unsigned int)1E6; e++; } /************************************ ** print mantissa (m1.m2) */ m1 = m2 / 1000000; m2 -= m1 * 1000000; if (n.p.sign) *buf++ = '-'; buf = int2str(m1, buf, 0); *buf++ = '.'; buf = int2str(m2, buf, 6); /************************************ ** print decimal exponent */ *buf++ = 'e'; if (e < 0) { *buf++ = '-'; e = -e; } else *buf++ = '+'; buf = int2str(e, buf, 2); return argbuf;}/************************************************************************ * Implementation : Public functions ************************************************************************//************************************************************************ * * main * Description : * ------------- * main function. Simply prints a few lines and exits to YAMON * * Return values : * --------------- * Always 0 * ************************************************************************/int main( t_yamon_uint32 argc, /* Number of tokens in argv array */ char **argv, /* Array of tokens (first is "go") */ t_yamon_env_var *env, /* Array of env. variables */ t_yamon_uint32 memsize ) /* Size of memory (byte count) */{ t_number x, y, z; char buf1[20], buf2[20], buf3[20]; puts("---FPU emulator tests---\n"); puts("Type 'help fpu' for an explanation of the floating point unit options.\n"); puts("Type 'fpu' to see current settings.\n"); puts("Please expect a register dump if 'fpu emul' shows 'FPU emul off':\n\n"); puts("Number of double precision regs.\n"); puts("This example shows how a normal single precision load into register f5\n"); puts("destroys the content of double precision register f4 when fr is off.\n"); puts(" (fr on: 3.00e+00 / fr off: 6.553600e+04):\n"); x.l = 0x3f800000; /* 1.0 */ y.l = 0x40000000; /* 2.0 */ my_dadd(&z.f, &x.f, &y.f); printf("%s + %s = %s\n\n",f2str(x.l,buf1), f2str(y.l,buf2), f2str(z.l,buf3)); puts("Flush to zero (fs on: 0.00e+00 / fs off: den 4.203895e-45):\n"); x.l = 1; /* denormalized number */ y.l = 2; /* denormalized number */ my_add(&z.f, &x.f, &y.f); printf("%s + %s = %s\n\n",f2str(x.l,buf1), f2str(y.l,buf2), f2str(z.l,buf3)); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -