#include <perms.h>
#include "..."
extern void CALLSIGNAL(void) /* See
                                https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html
                              */
    ;                        /*perm*/
void PRIMDIV(void) {
  _imp_enter();

  label... label... label... asm("CMPS   _ R2, #0");
  asm("BNE    _ L0");
  asm("MOV _ R1, #14;");
  asm("MOV _ R2, #2;");
  asm("MOV _ R3, #0");
  asm("STMDB _ Sp!, <R1, R2, R3, Fp, Sb, Link>");
  CALLSIGNAL();
L0:;
  asm("MOV    _ R4, #1                {result sign}");
  asm("RSBLT  _ R2, R2, #0            {R2 = |R2|}");
  asm("RSBLT  _ R4, R4, #0            {invert result sign}");
  asm("ADDS   _ R5, R1, #0            {preserve Dividend & test sign}");
  asm("RSBLT  _ R1, R1, #0            {R1 = |R1|}");
  asm("RSBLT  _ R4, R4, #0            {invert result sign}");
  asm("MOV    _ R3, #1");

L1:;
  asm("CMPS   _ R2, #16_80000000");
  asm("CMPCCS _ R2, R1");
  asm("MOVCC  _ R2, R2, %LSL #1");
  asm("MOVCC  _ R3, R3, %LSL #1");
  asm("BCC    _ L1");
  asm("MOV    _ R0, #0");

L2:;
  asm("CMPS   _ R1, R2");
  asm("SUBCS  _ R1, R1, R2");
  asm("ADDCS  _ R0, R0, R3");
  asm("MOVS   _ R3, R3, %LSR #1");
  asm("MOVNE  _ R2, R2, %LSR #1");
  asm("BNE    _ L2");
  asm("CMPS   _ R4, #0");
  asm("RSBLT  _ R0, R0, #0         {negate quotient}");
  asm("CMPS   _ R5, #0");
  asm("RSBLT  _ R1, R1, #0         {negate remainder}");
  asm("MOV    _ Pc, Link");

  _imp_leave();
}
