ZealOS/src/Demo/Lectures/InterruptDemo.CC
Void NV c6dddb932b Rewrote IntEntry functions. Added CIDTEntry.
Removed DPL argument from IntEntrySet.
Updated OS version to 1.12.
2020-04-12 17:14:55 -05:00

87 lines
1.6 KiB
C++
Executable File

//This is the software interrupt num
//we will use. See $LK,"Software Int's",A="MN:I_WAKE"$ 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=TSCGet;
for (i=0;i<SAMPLE_SIZE;i++)
UnaryMinusInt(ã);
end=TSCGet;
"Interrupt Cycles: %10.5f\n",ToF64(end-start)/SAMPLE_SIZE;
//Measure call time
start=TSCGet;
for (i=0;i<SAMPLE_SIZE;i++)
UnaryMinusCall(ã);
end=TSCGet;
"Call Cycles: %10.5f\n",ToF64(end-start)/SAMPLE_SIZE;
IntEntrySet(I_F_UNARY_MINUS,old_irq,IDTET_IRQ);
}
TimeIns;
/* Program Output$HL,0$$WW+H,1$$FD,1$
$PT$$FG$$BG$6 Cores 3.395GHz
Interrupt Cycles: 573.98543
Call Cycles: 9.74349
$HL,1$*/