zylin / zpugcc

50 stars 32 forks source link

Optional opcode flags not working #8

Open madscientist159 opened 7 years ago

madscientist159 commented 7 years ago

At least the -mmult and -mdiv flags have no effect; the generated assembly continues to call into the emulated division routines and the mul opcode is nowhere to be found in the output.

Test code:

int main() {
    unsigned int counter = 0;
    counter++;
    *debug_port = counter / 3;
}

Compiler flags: zpu-elf-gcc -O0 -S -mmult -mdiv main.c

Generated assembly: impcrel (__udivsi3)

Expected output: div

alvieboy commented 7 years ago

Odd it even calls __udivsi3 in this situation, since it boils down to a constant value. Can you place "unsigned int counter = 0" outside main, and recheck ?

madscientist159 commented 7 years ago

@alvieboy I reduced the test case too much, sorry. Here's the full (tested) minimal code:

volatile unsigned int* debug_port = (void *)<memory address>;

int main(int argc, char *argv) {
    unsigned int counter = 0x0;

    while (1) {
        counter++;
        *debug_port = counter / 3;
    }
}
alvieboy commented 7 years ago

I confirm div is not being issued. Mul should be issued if you use it though.

I'll try to fix the behaviour as soon as possible.

Do you have div implemented in hardware ? Otherwise, the emulation code will probably call __udivsi3 anyway, making your code larger and slower.

madscientist159 commented 7 years ago

I'll double check on mul; the disassembly output for

*debug_port = (counter * 5) / 3;

did not contain mul, I don't know if this is because it was optimized away even at O0 somehow or if there is an additional bug.

Yes, the hardware in question has a hardware divider. I only caught the missing div call because the division operations were taking far too long to execute given the dedicated hardware resources.

alvieboy commented 7 years ago

It's optimization. Check with "debug_port = (counter 13 ) /3;". Note that for some multiplications, GCC will also emit multiple additions. Not sure what is the threshold from top of my head.

madscientist159 commented 7 years ago

Thanks, that's what I had thought. I saw the additions and was wondering if something had been optimized.

Any ETA on a fix for the div problem?

Thanks!

alvieboy commented 7 years ago

Hopefully will have time this weekend. I'll let you know.

alvieboy commented 7 years ago

Ah... I see something that might explain why you are not getting a "div". You are dividing unsigned numbers. The implementation of div is supposed to be signed. Need to think a bit about how to best implement this for unsigned numbers.

madscientist159 commented 7 years ago

I also tried

*debug_port = (int)counter / 3;

No joy.

alvieboy commented 7 years ago

Can you email me at alvieboy at alvie dot com ? Not to pollute this bugreport too much.