//This is the software interrupt num //we will use. See Software Int's for //picking a num. Nums are subject to change. #define I_F_UNARY_MINUS I_USER asm { //This changes the sign of the floating //point val in RAX F_UNARY_MINUS_INT:: PUSH RAX FLD U64 [RSP] FCHS FSTP U64 [RSP] POP RAX IRET //This does the same thing, but not as //an interrupt. F_UNARY_MINUS_CALL:: PUSH RAX FLD U64 [RSP] FCHS FSTP U64 [RSP] POP RAX RET //This invokes the interrupt version //with a C callable function. _F_UM_INT:: PUSH RBP MOV RBP,RSP MOV RAX,SF_ARG1[RBP] INT I_F_UNARY_MINUS POP RBP RET1 8 //This invokes the call version //with a C callable function. _F_UM_CALL:: PUSH RBP MOV RBP,RSP MOV RAX,SF_ARG1[RBP] CALL F_UNARY_MINUS_CALL POP RBP RET1 8 } _extern _F_UM_INT F64 UnaryMinusInt(F64 d); _extern _F_UM_CALL F64 UnaryMinusCall(F64 d); #define SAMPLE_SIZE 1000000 U0 TimeIns() { I64 start,end; I64 i,old_irq; CPURep; old_irq=IntEntrySet(I_F_UNARY_MINUS,F_UNARY_MINUS_INT,IDTET_TRAP); //Measure interrupt time start=GetTSC; for (i=0; i<SAMPLE_SIZE; i++) UnaryMinusInt(pi); end=GetTSC; "Interrupt Cycles: %10.5f\n" ,ToF64(end-start)/SAMPLE_SIZE; //Measure call time start=GetTSC; for (i=0; i<SAMPLE_SIZE; i++) UnaryMinusCall(pi); end=GetTSC; "Call Cycles: %10.5f\n" ,ToF64(end-start)/SAMPLE_SIZE; IntEntrySet(I_F_UNARY_MINUS,old_irq,IDTET_IRQ); } TimeIns; /* Program Output 6 Cores 3.395GHz Interrupt Cycles: 573.98543 Call Cycles: 9.74349 */