// File: /workspace/github_c_makefile_star2_O0/OnionIoT[P]lv_example/lvgl/src/lv_misc/lv_math.c
// Function: lv_atan2
uint16_t lv_atan2(int x, int y)
{
    // Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com
    // Converts any XY values including 0 to a degree value that should be
    // within +/- 1 degree of the accurate value without needing
    // large slow trig functions like ArcTan() or ArcCos().
    // NOTE! at least one of the X or Y values must be non-zero!
    // This is the full version, for all 4 quadrants and will generate
    // the angle in integer degrees from 0-360.
    // Any values of X and Y are usable including negative values provided
    // they are between -1456 and 1456 so the 16bit multiply does not overflow.

    unsigned char negflag;
    unsigned char tempdegree;
    unsigned char comp;
    unsigned int degree;     // this will hold the result
    //signed int x;            // these hold the XY vector at the start
    //signed int y;            // (and they will be destroyed)
    unsigned int ux;
    unsigned int uy;

    // Save the sign flags then remove signs and get XY as unsigned ints
    negflag = 0;
    if(x < 0) {
        negflag += 0x01;    // x flag bit
        x = (0 - x);        // is now +
    }
    ux = x;                // copy to unsigned var before multiply
    if(y < 0) {
        negflag += 0x02;    // y flag bit
        y = (0 - y);        // is now +
    }
    uy = y;                // copy to unsigned var before multiply

    // 1. Calc the scaled "degrees"
    if(ux > uy) {
        degree = (uy * 45) / ux;   // degree result will be 0-45 range
        negflag += 0x10;    // octant flag bit
    } else {
        degree = (ux * 45) / uy;   // degree result will be 0-45 range
    }

    // 2. Compensate for the 4 degree error curve
    comp = 0;
    tempdegree = degree;    // use an unsigned char for speed!
    if(tempdegree > 22) {    // if top half of range
        if(tempdegree <= 44) comp++;
        if(tempdegree <= 41) comp++;
        if(tempdegree <= 37) comp++;
        if(tempdegree <= 32) comp++;  // max is 4 degrees compensated
    } else { // else is lower half of range
        if(tempdegree >= 2) comp++;
        if(tempdegree >= 6) comp++;
        if(tempdegree >= 10) comp++;
        if(tempdegree >= 15) comp++;  // max is 4 degrees compensated
    }
    degree += comp;   // degree is now accurate to +/- 1 degree!

    // Invert degree if it was X>Y octant, makes 0-45 into 90-45
    if(negflag & 0x10) degree = (90 - degree);

    // 3. Degree is now 0-90 range for this quadrant,
    // need to invert it for whichever quadrant it was in
    if(negflag & 0x02) { // if -Y
        if(negflag & 0x01)   // if -Y -X
            degree = (180 + degree);
        else        // else is -Y +X
            degree = (180 - degree);
    } else { // else is +Y
        if(negflag & 0x01)   // if +Y -X
            degree = (360 - degree);
    }
    return degree;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movb $0x0, -0x9(%rbp)
cmpl $0x0, -0x4(%rbp)
jge 0x473f6
movzbl -0x9(%rbp), %eax
addl $0x1, %eax
movb %al, -0x9(%rbp)
xorl %eax, %eax
subl -0x4(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x8(%rbp)
jge 0x47414
movzbl -0x9(%rbp), %eax
addl $0x2, %eax
movb %al, -0x9(%rbp)
xorl %eax, %eax
subl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movl -0x8(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
jbe 0x4743a
imull $0x2d, -0x18(%rbp), %eax
xorl %edx, %edx
divl -0x14(%rbp)
movl %eax, -0x10(%rbp)
movzbl -0x9(%rbp), %eax
addl $0x10, %eax
movb %al, -0x9(%rbp)
jmp 0x47446
imull $0x2d, -0x14(%rbp), %eax
xorl %edx, %edx
divl -0x18(%rbp)
movl %eax, -0x10(%rbp)
movb $0x0, -0xb(%rbp)
movl -0x10(%rbp), %eax
movb %al, -0xa(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0x16, %eax
jle 0x4749f
movzbl -0xa(%rbp), %eax
cmpl $0x2c, %eax
jg 0x4746a
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0x29, %eax
jg 0x4747b
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0x25, %eax
jg 0x4748c
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0x20, %eax
jg 0x4749d
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
jmp 0x474e5
movzbl -0xa(%rbp), %eax
cmpl $0x2, %eax
jl 0x474b0
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0x6, %eax
jl 0x474c1
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0xa, %eax
jl 0x474d2
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
movzbl -0xa(%rbp), %eax
cmpl $0xf, %eax
jl 0x474e3
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
jmp 0x474e5
movzbl -0xb(%rbp), %eax
addl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
movzbl -0x9(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x47506
movl $0x5a, %eax
subl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
movzbl -0x9(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x47538
movzbl -0x9(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x4752b
movl -0x10(%rbp), %eax
addl $0xb4, %eax
movl %eax, -0x10(%rbp)
jmp 0x47536
movl $0xb4, %eax
subl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
jmp 0x47551
movzbl -0x9(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x4754f
movl $0x168, %eax            # imm = 0x168
subl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
jmp 0x47551
movl -0x10(%rbp), %eax
popq %rbp
retq
nopw %cs:(%rax,%rax)