【UEFI基础】VS2017 编译 EDK2 Stdlib

需要编译一个UEFI下的应用程序,需要用到StdLib, 但使用VS2017 + edk2201905 或edk2-vUDK2018都编译不通过, 一直提示:LibGdtoa.lib(ldtoa.obj) : error LNK2001: 无法解析的外部符号 ___fpclassifyd。

查看发现是ldtoa.c调用math.h, 在math.h中有声明:
/*
Library implementation
*/
int __fpclassifyf(float);
int __fpclassifyd(double);
其它类似函数在LibC\Main下都有实现,但__fpclassifyf和__fpclassifyd没有实现。 所以手动实现这两个函数。 参照其它类似函数,将这个实现文件放在Main目录下编译进LibC(中间走了许多弯路,最后才发现只需要放在Main下,编译进LibC库就可以).
源文件参考了资源1, 实际只需要实现__fpclassifyf(float)和__fpclassifyd(double)。 在LibC.inf中,在[Sources]添加此文件 Main/fpclassify.c。
/* fpclassify.c */
#include <sys/types.h>
#include <math.h>
#include <machine/ieee.h>
union float_u {
    float f;
    struct ieee_single bits;
};
union double_u {
    double d;
    struct ieee_double bits;
};
int __fpclassifyd(double d){
    union double_u u;
    u.d=d;
    if(u.bits.dbl_exp==0){ 
        return ((u.bits.dbl_fracl | u.bits.dbl_frach)==0)?FP_ZERO : FP_SUBNORMAL;
    }
    if(u.bits.dbl_exp == DBL_EXP_INFNAN){
        return ((u.bits.dbl_fracl | u.bits.dbl_frach)==0) ?FP_INFINITE : FP_NAN;
    }
    return FP_NORMAL;
}
int __fpclassifyf(float f ){
    union float_u u;
    u.f=f;
    if(u.bits.sng_exp == 0) {
        return (u.bits.sng_frac == 0 )? FP_ZERO : FP_SUBNORMAL;
    }
    if(u.bits.sng_exp==SNG_EXP_INFNAN){
        return (u.bits.sng_frac == 0)? FP_INFINITE : FP_NAN;
    }
    return FP_NORMAL;
}
int __isinf(double d){
    return (__fpclassifyd(d) == FP_INFINITE);
}
int __isnan(double d) {
  return (__fpclassifyd(d) == FP_NAN);
}
int __isfinite(double d) {
  int type = __fpclassifyd(d);
  return ((type != FP_NAN) && (type != FP_INFINITE));
}
int __isfinitef(float f) {
  int type = __fpclassifyf(f);
  return ((type != FP_NAN) && (type != FP_INFINITE));
}
int __isnormal(double d) {
  return (__fpclassifyd(d) == FP_NORMAL);
}
int __isnormalf(float f) {
  return (__fpclassifyf(f) == FP_NORMAL);
}
#ifdef __HAVE_LONG_DOUBLE
union long_double_u {
  long double ld;
  struct ieee_ext bits;
};
#define zero_frac(b) ((b.ext_fracl | b.ext_frach ) == 0)
int __fpclassifyl(long double ld) {
  union long_double_u u;
  u.ld = ld;
  if (u.bits.ext_exp == 0) {
    return zero_frac(u.bits) ? FP_ZERO : FP_SUBNORMAL;
  }
  if (u.bits.ext_exp == EXT_EXP_INFNAN) {
    return zero_frac(u.bits) ? FP_INFINITE : FP_NAN;
  }
  return FP_NORMAL;
}
int __isfinitel(long double ld) {
  int type = __fpclassifyl(ld);
  return ((type != FP_NAN) && (type != FP_INFINITE));
}
int __isnormall(long double ld) {
  return (__fpclassifyl(ld) == FP_NORMAL);
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值