gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Two questions: peter teichman and fixed point math

#21026 - alek - Fri May 21, 2004 7:55 pm

Hi.

I have two questions:
Peter teichman writes:

Code:

/* if you need both quotient and reminder */
extern __value_in_regs udiv_t FDIV(unsigned int a, unsigned int b);
extern __value_in_regs div_t FDIVS(int a, int b);


for his division routine what does
__value_in_regs udiv_t and
__value_in_regs div_t
mean?
what should be there instead?

My second question:
I got this fixed point multiplication code from tepples

Code:

@ int fixmul(int a, int b)
    .ARM
    .ALIGN
    .GLOBL fixmul

fixmul:
  smull r1, r2, r0, r1     @ r2:r1 = (long long)r0 * r1
  mov r0, r2, lsl #16      @ r0 = r2 << 16
  orr r0, r0, r1, lsr #16  @ r0 |= (unsigned int)r1 >> 16
  bx lr                    @ return r0


what changes do I need to do to get it to work with 20:12 fixed point numbers.

Thanks.

#21029 - Miked0801 - Fri May 21, 2004 10:41 pm

The val_in_regs thing didn't work with my version of GCC so I returned one of the values through arguments.

TO make the assembly work with 20:12, you'd need to change the lsl #16 to lsl #20 and the lsr #16 to lsr #12.

Someone else confirm please?

#21030 - alek - Fri May 21, 2004 10:45 pm

Miked0801 wrote:


TO make the assembly work with 20:12, you'd need to change the lsl #16 to lsl #20 and the lsr #16 to lsr #12.

Someone else confirm please?


I've already tried that and unless I'm doing something else wrong that change doesn't work...

#21037 - tepples - Sat May 22, 2004 2:15 am

You might have to play with the values until you get them right. Try rigging up a text interface that multiplies two numbers and then prints the hex result. You'll quickly learn how many bits you are off.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#21042 - alek - Sat May 22, 2004 9:07 am

I did what tepples said and found out that I should change
lsl#16 to lsl#12 and
lsr#16 to lsr#20

I got it wrong before I meant 12:20 fixed point numbers so Miked0801 was right:)

But when I put it in my project it freaks out...

I change

Code:

f[1]=setup[mode][number].a12*Divfx(power3(r12),Mulfx(m2,(u[4]-u[0])))+
         setup[mode][number].a13*Divfx(power3(r31),Mulfx(m3,(u[8]-u[0])));


where
Code:

#define BITS 20
#define FACTOR 1048576
#define Mulfx(x,y) (((long long)y * x)>>BITS)      // Multiply a fixed by a fixed
#define Divfx(x,y) (((long long)y*FACTOR) / (x))    //Divide a fixed by a fixed


with
Code:

f[1]=setup[mode][number].a12*Divfx(power3(r12),fixmul(m2,(u[4]-u[0])))+
         setup[mode][number].a13*Divfx(power3(r31),fixmul(m3,(u[8]-u[0])));

where
Code:

@ int fixmul(int a, int b)
    .ARM
    .ALIGN
    .GLOBL fixmul

fixmul:
  smull r1, r2, r0, r1     @ r2:r1 = (long long)r0 * r1
  mov r0, r2, lsl #12      @ r0 = r2 << 16
  orr r0, r0, r1, lsr #20  @ r0 |= (unsigned int)r1 >> 16
  bx lr 

#21062 - alek - Sat May 22, 2004 5:45 pm

it seems like the fixmul version only freaks out in special cases but I can't find the values for when it goes from working to freaking out... shouldn't the fixmul and Mulfx behave the same way?

#21064 - alek - Sat May 22, 2004 7:20 pm

I got it to work but I had to change some other numbers... I still don't understand why it didn't work before... Why doesn't the fixmul and Mulfx posted above work precisley the same?