On 5.4.2012 15:11, Jakub Jermar wrote:
> Anyway, I am going to make myself a small SPARC sample and see...

Ok, here are the results:

#include <libarch/ddi.h>
#include <stdint.h>

typedef struct {
        uint8_t a;
        uint32_t b;
} __attribute__ ((packed)) my_regs_t;

uint32_t main(int argc, char **argv)
{
        my_regs_t *regs = (void *) argv;

        return *((ioport32_t *) &regs->b);
}

Produces this:

00000000000040e0 <main>:
    40e0:       d0 02 60 01     ld  [ %o1 + 1 ], %o0    ; 32-bit access
    40e4:       81 c3 e0 08     retl
    40e8:       01 00 00 00     nop
    40ec:       30 68 00 05     b,a   %xcc, 4100 <exit>

Modifying the return statement to read like this:

        return *((uint32_t *) &regs->b);

gives us the following output:

00000000000040e0 <main>:
    40e0:       c6 0a 60 01     ldub  [ %o1 + 1 ], %g3  ; 8-bit access
    40e4:       c2 0a 60 02     ldub  [ %o1 + 2 ], %g1  ; 8-bit access
    40e8:       c4 0a 60 03     ldub  [ %o1 + 3 ], %g2  ; 8-bit access
    40ec:       87 28 f0 18     sllx  %g3, 0x18, %g3
    40f0:       83 28 70 10     sllx  %g1, 0x10, %g1
    40f4:       d0 0a 60 04     ldub  [ %o1 + 4 ], %o0  ; 8-bit access
    40f8:       85 28 b0 08     sllx  %g2, 8, %g2
    40fc:       82 10 40 03     or  %g1, %g3, %g1
    4100:       82 10 80 01     or  %g2, %g1, %g1
    4104:       81 c3 e0 08     retl
    4108:       90 12 00 01     or  %o0, %g1, %o0

I think what helps in the first example is both the cast to a volatile
qualified type and also the reference operator. Note that changing the
example as follows, gives us a bad result too:

#include <libarch/ddi.h>
#include <stdint.h>

typedef struct {
        ioport8_t a;
        ioport32_t b;
} __attribute__ ((packed)) my_regs_t;

uint32_t main(int argc, char **argv)
{
        my_regs_t *regs = (void *) argv;

        return regs->b;
}

00000000000040e0 <main>:
    40e0:       c6 0a 60 01     ldub  [ %o1 + 1 ], %g3
    40e4:       c2 0a 60 02     ldub  [ %o1 + 2 ], %g1
    40e8:       c4 0a 60 03     ldub  [ %o1 + 3 ], %g2
    40ec:       87 28 f0 18     sllx  %g3, 0x18, %g3
    40f0:       83 28 70 10     sllx  %g1, 0x10, %g1
    40f4:       d0 0a 60 04     ldub  [ %o1 + 4 ], %o0
    40f8:       85 28 b0 08     sllx  %g2, 8, %g2
    40fc:       82 10 40 03     or  %g1, %g3, %g1
    4100:       82 10 80 01     or  %g2, %g1, %g1
    4104:       81 c3 e0 08     retl
    4108:       90 12 00 01     or  %o0, %g1, %o0

On the other hand, using pio_read_32() helps again:

        return pio_read_32(&regs->b);

00000000000040e0 <main>:
    40e0:       d0 02 60 01     ld  [ %o1 + 1 ], %o0
    40e4:       81 43 e0 09     membar  #StoreStore|#LoadLoad
    40e8:       81 c3 e0 08     retl
    40ec:       91 32 20 00     srl  %o0, 0, %o0
    40f0:       30 68 00 04     b,a   %xcc, 4100 <exit>

Now, what do we conclude from it?

Jakub

_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/cgi-bin/listinfo/helenos-devel

Reply via email to