#include <amd64/intr_defs.h>
#include <amd64/regsasm.h>

.extern intr_handler

#define err(z) \
  pushq $z;

#define no_err(z) \
  pushq $0;       \
  pushq $z;

#define make_intr_stub(x, n)    \
  .global intr ## n;      \
  intr ## n:;             \
  x(n);                         \
  cli;                          \
  ;                             \
  push_regs;                    \
  ;                             \
  movw $0x10, %ax;              \
  movw %ax, %ds;                \
  movw %ax, %es;                \
  ;                             \
  cld;                          \
  ;                             \
  movq %rsp, %rdi;              \
  ;                             \
  movq %cr3, %rax; pushq %rax;  \
  ;                             \
  movq %rsp, %rbp;              \
  ;                             \
  andq $-16, %rsp;              \
  ;                             \
  callq intr_handler;     \
  ;                             \
  movq %rbp, %rsp;              \
  ;                             \
  popq %rax; movq %rax, %cr3;   \
  ;                             \
  pop_regs;                     \
  addq $16, %rsp;               \
  ;                             \
  iretq;
  

make_intr_stub(no_err, 0)
make_intr_stub(no_err, 1)
make_intr_stub(no_err, 2)
make_intr_stub(no_err, 3)
make_intr_stub(no_err, 4)
make_intr_stub(no_err, 5)
make_intr_stub(no_err, 6)
make_intr_stub(no_err, 7)
make_intr_stub(err, 8)
make_intr_stub(no_err, 9)
make_intr_stub(err, 10)
make_intr_stub(err, 11)
make_intr_stub(err, 12)
make_intr_stub(err, 13)
make_intr_stub(err, 14)
make_intr_stub(no_err, 15)
make_intr_stub(no_err, 16)
make_intr_stub(err, 17)
make_intr_stub(no_err, 18)
make_intr_stub(no_err, 19)
make_intr_stub(no_err, 20)
make_intr_stub(err, 21)
make_intr_stub(no_err, 22)
make_intr_stub(no_err, 23)
make_intr_stub(no_err, 24)
make_intr_stub(no_err, 25)
make_intr_stub(no_err, 26)
make_intr_stub(no_err, 27)
make_intr_stub(no_err, 28)
make_intr_stub(err, 29)
make_intr_stub(err, 30)
make_intr_stub(no_err, 31)
make_intr_stub(no_err, 32)
make_intr_stub(no_err, 33)
make_intr_stub(no_err, 34)
make_intr_stub(no_err, 35)
make_intr_stub(no_err, 36)
make_intr_stub(no_err, 37)
make_intr_stub(no_err, 38)
make_intr_stub(no_err, 39)
make_intr_stub(no_err, 40)
make_intr_stub(no_err, 41)
make_intr_stub(no_err, 42)
make_intr_stub(no_err, 43)
make_intr_stub(no_err, 44)
make_intr_stub(no_err, 45)
make_intr_stub(no_err, 46)
make_intr_stub(no_err, 47)

make_intr_stub(no_err, SCHED_PREEMPT_TIMER)
make_intr_stub(no_err, CPU_REQUEST_SCHED)
make_intr_stub(no_err, CPU_SPURIOUS)
