C-sparse

 view release on metacpan or  search on metacpan

src/sparse-0.4.4/perl/t/tcg/s390/tcg-target.c  view on Meta::CPAN

    { INDEX_op_ld16u_i64, { "r", "r" } },
    { INDEX_op_ld16s_i64, { "r", "r" } },
    { INDEX_op_ld32u_i64, { "r", "r" } },
    { INDEX_op_ld32s_i64, { "r", "r" } },
    { INDEX_op_ld_i64, { "r", "r" } },

    { INDEX_op_st8_i64, { "r", "r" } },
    { INDEX_op_st16_i64, { "r", "r" } },
    { INDEX_op_st32_i64, { "r", "r" } },
    { INDEX_op_st_i64, { "r", "r" } },

    { INDEX_op_add_i64, { "r", "r", "ri" } },
    { INDEX_op_sub_i64, { "r", "0", "ri" } },
    { INDEX_op_mul_i64, { "r", "0", "rK" } },

    { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
    { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
    { INDEX_op_mulu2_i64, { "b", "a", "0", "r" } },

    { INDEX_op_and_i64, { "r", "0", "ri" } },
    { INDEX_op_or_i64, { "r", "0", "rO" } },
    { INDEX_op_xor_i64, { "r", "0", "rX" } },

    { INDEX_op_neg_i64, { "r", "r" } },

    { INDEX_op_shl_i64, { "r", "r", "Ri" } },
    { INDEX_op_shr_i64, { "r", "r", "Ri" } },
    { INDEX_op_sar_i64, { "r", "r", "Ri" } },

    { INDEX_op_rotl_i64, { "r", "r", "Ri" } },
    { INDEX_op_rotr_i64, { "r", "r", "Ri" } },

    { INDEX_op_ext8s_i64, { "r", "r" } },
    { INDEX_op_ext8u_i64, { "r", "r" } },
    { INDEX_op_ext16s_i64, { "r", "r" } },
    { INDEX_op_ext16u_i64, { "r", "r" } },
    { INDEX_op_ext32s_i64, { "r", "r" } },
    { INDEX_op_ext32u_i64, { "r", "r" } },

    { INDEX_op_bswap16_i64, { "r", "r" } },
    { INDEX_op_bswap32_i64, { "r", "r" } },
    { INDEX_op_bswap64_i64, { "r", "r" } },

    { INDEX_op_add2_i64, { "r", "r", "0", "1", "r", "r" } },
    { INDEX_op_sub2_i64, { "r", "r", "0", "1", "r", "r" } },

    { INDEX_op_brcond_i64, { "r", "rC" } },
    { INDEX_op_setcond_i64, { "r", "r", "rC" } },
    { INDEX_op_movcond_i64, { "r", "r", "rC", "r", "0" } },
    { INDEX_op_deposit_i64, { "r", "0", "r" } },

    { INDEX_op_qemu_ld32u, { "r", "L" } },
    { INDEX_op_qemu_ld32s, { "r", "L" } },

    { -1 },
};

/* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
   this information.  However, getting at that entry is not easy this far
   away from main.  Our options are: start searching from environ, but
   that fails as soon as someone does a setenv in between.  Read the data
   from /proc/self/auxv.  Or do the probing ourselves.  The only thing
   extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
   that the kernel saves all 64-bits of the registers around traps while
   in 31-bit mode.  But this is true of all "recent" kernels (ought to dig
   back and see from when this might not be true).  */

#include <signal.h>

static volatile sig_atomic_t got_sigill;

static void sigill_handler(int sig)
{
    got_sigill = 1;
}

static void query_facilities(void)
{
    struct sigaction sa_old, sa_new;
    register int r0 __asm__("0");
    register void *r1 __asm__("1");
    int fail;

    memset(&sa_new, 0, sizeof(sa_new));
    sa_new.sa_handler = sigill_handler;
    sigaction(SIGILL, &sa_new, &sa_old);

    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
       we need not do any more probing.  Unfortunately, this itself is an
       extension and the original STORE FACILITY LIST instruction is
       kernel-only, storing its results at absolute address 200.  */
    /* stfle 0(%r1) */
    r1 = &facilities;
    asm volatile(".word 0xb2b0,0x1000"
                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");

    if (got_sigill) {
        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
           kind of instruction that we're interested in.  */
        /* ??? Possibly some of these are in practice never present unless
           the store-facility-extended facility is also present.  But since
           that isn't documented it's just better to probe for each.  */

        /* Test for z/Architecture.  Required even in 31-bit mode.  */
        got_sigill = 0;
        /* agr %r0,%r0 */
        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
        if (!got_sigill) {
            facilities |= FACILITY_ZARCH_ACTIVE;
        }

        /* Test for long displacement.  */
        got_sigill = 0;
        /* ly %r0,0(%r1) */
        r1 = &facilities;
        asm volatile(".word 0xe300,0x1000,0x0058"
                     : "=r"(r0) : "r"(r1) : "cc");
        if (!got_sigill) {
            facilities |= FACILITY_LONG_DISP;
        }



( run in 2.062 seconds using v1.01-cache-2.11-cpan-fe3c2283af0 )