/*NetWinderFloatingPointEmulator(c)Rebel.COM,1998,1999(c)PhilipBlundell,1999Directquestions,commentstoScottBambrough<scottb@netwinder.org>Thisprogramisfreesoftware;youcanredistributeitand/ormodifyitunderthetermsoftheGNUGeneralPublicLicenseaspublishedbytheFreeSoftwareFoundation;eitherversion2oftheLicense,or(atyouroption)anylaterversion.Thisprogramisdistributedinthehopethatitwillbeuseful,butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyofMERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.SeetheGNUGeneralPublicLicenseformoredetails.YoushouldhavereceivedacopyoftheGNUGeneralPublicLicensealongwiththisprogram;ifnot,writetotheFreeSoftwareFoundation,Inc.,675MassAve,Cambridge,MA02139,USA.*/#include"fpa11.h"#include"softfloat.h"#include"fpopcode.h"#include"fpa11.inl"//#include"fpmodule.h"//#include"fpmodule.inl"voidSetRoundingMode(constunsignedintopcode);unsignedintPerformFLT(constunsignedintopcode);unsignedintPerformFIX(constunsignedintopcode);staticunsignedintPerformComparison(constunsignedintopcode);unsignedintEmulateCPRT(constunsignedintopcode){unsignedintnRc=1;//printk("EmulateCPRT(0x%08x)\n",opcode);if(opcode&0x800000){/*Thisissomevariantofacomparison(PerformComparisonwillsortoutwhichone).SincemostoftheotherCPRTinstructionsareoddballcasesofsomesortorotheritmakessensetopullthisoutintoafastpath.*/returnPerformComparison(opcode);}/* Hint to GCC that we'd like a jump table rather than a load of CMPs */switch((opcode&0x700000)>>20){caseFLT_CODE>>20:nRc=PerformFLT(opcode);break;caseFIX_CODE>>20:nRc=PerformFIX(opcode);break;
staticunsignedintPerformComparison(constunsignedintopcode){FPA11*fpa11=GET_FPA11();unsignedintFn,Fm;floatx80rFn,rFm;inte_flag=opcode&0x400000;/* 1 if CxFE */intn_flag=opcode&0x200000;/* 1 if CNxx */unsignedintflags=0;//printk("PerformComparison(0x%08x)\n",opcode);Fn=getFn(opcode);Fm=getFm(opcode);/*Checkforunorderedconditionandconvertalloperandsto80-bitformat.??Mightbesomemileageinavoidingthisconversionifpossible.Eg,ifbothoperandsare32-bit,detectthisanddoa32-bitcomparison(cheaperthanan80-bitone).*/switch(fpa11->fType[Fn]){
default:return0;}if(CONSTANT_FM(opcode)){//printk("Fm is a constant: #%d.\n",Fm);rFm=getExtendedConstant(Fm);if(floatx80_is_nan(rFm))gotounordered;}else{//printk("Fm = r%d which contains a ",Fm);switch(fpa11->fType[Fm]){