qemu/tests/tcg/s390x/shift.c
<<
>>
Prefs
   1#include <inttypes.h>
   2#include <stdint.h>
   3#include <stdio.h>
   4
   5#define DEFINE_SHIFT_SINGLE_COMMON(_name, _insn_str) \
   6    static uint64_t _name(uint64_t op1, uint64_t op2, uint64_t *cc) \
   7    { \
   8        asm("    sll %[cc],28\n" \
   9            "    spm %[cc]\n" \
  10            "    " _insn_str "\n" \
  11            "    ipm %[cc]\n" \
  12            "    srl %[cc],28" \
  13            : [op1] "+&r" (op1), \
  14              [cc] "+&r" (*cc) \
  15            : [op2] "r" (op2) \
  16            : "cc"); \
  17        return op1; \
  18    }
  19#define DEFINE_SHIFT_SINGLE_2(_insn, _offset) \
  20    DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \
  21                               #_insn " %[op1]," #_offset "(%[op2])")
  22#define DEFINE_SHIFT_SINGLE_3(_insn, _offset) \
  23    DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \
  24                               #_insn " %[op1],%[op1]," #_offset "(%[op2])")
  25#define DEFINE_SHIFT_DOUBLE(_insn, _offset) \
  26    static uint64_t _insn ## _ ## _offset(uint64_t op1, uint64_t op2, \
  27                                          uint64_t *cc) \
  28    { \
  29        uint32_t op1h = op1 >> 32; \
  30        uint32_t op1l = op1 & 0xffffffff; \
  31        register uint32_t r2 asm("2") = op1h; \
  32        register uint32_t r3 asm("3") = op1l; \
  33        \
  34        asm("    sll %[cc],28\n" \
  35            "    spm %[cc]\n" \
  36            "    " #_insn " %[r2]," #_offset "(%[op2])\n" \
  37            "    ipm %[cc]\n" \
  38            "    srl %[cc],28" \
  39            : [r2] "+&r" (r2), \
  40              [r3] "+&r" (r3), \
  41              [cc] "+&r" (*cc) \
  42            : [op2] "r" (op2) \
  43            : "cc"); \
  44        op1h = r2; \
  45        op1l = r3; \
  46        return (((uint64_t)op1h) << 32) | op1l; \
  47    }
  48
  49DEFINE_SHIFT_SINGLE_3(rll, 0x4cf3b);
  50DEFINE_SHIFT_SINGLE_3(rllg, 0x697c9);
  51DEFINE_SHIFT_SINGLE_2(sla, 0x4b0);
  52DEFINE_SHIFT_SINGLE_2(sla, 0xd54);
  53DEFINE_SHIFT_SINGLE_3(slak, 0x2832c);
  54DEFINE_SHIFT_SINGLE_3(slag, 0x66cc4);
  55DEFINE_SHIFT_SINGLE_3(slag, 0xd54);
  56DEFINE_SHIFT_SINGLE_2(sll, 0xd04);
  57DEFINE_SHIFT_SINGLE_3(sllk, 0x2699f);
  58DEFINE_SHIFT_SINGLE_3(sllg, 0x59df9);
  59DEFINE_SHIFT_SINGLE_2(sra, 0x67e);
  60DEFINE_SHIFT_SINGLE_3(srak, 0x60943);
  61DEFINE_SHIFT_SINGLE_3(srag, 0x6b048);
  62DEFINE_SHIFT_SINGLE_2(srl, 0x035);
  63DEFINE_SHIFT_SINGLE_3(srlk, 0x43dfc);
  64DEFINE_SHIFT_SINGLE_3(srlg, 0x27227);
  65DEFINE_SHIFT_DOUBLE(slda, 0x38b);
  66DEFINE_SHIFT_DOUBLE(sldl, 0x031);
  67DEFINE_SHIFT_DOUBLE(srda, 0x36f);
  68DEFINE_SHIFT_DOUBLE(srdl, 0x99a);
  69
  70struct shift_test {
  71    const char *name;
  72    uint64_t (*insn)(uint64_t, uint64_t, uint64_t *);
  73    uint64_t op1;
  74    uint64_t op2;
  75    uint64_t exp_result;
  76    uint64_t exp_cc;
  77};
  78
  79static const struct shift_test tests[] = {
  80    {
  81        .name = "rll",
  82        .insn = rll_0x4cf3b,
  83        .op1 = 0xecbd589a45c248f5ull,
  84        .op2 = 0x62e5508ccb4c99fdull,
  85        .exp_result = 0xecbd589af545c248ull,
  86        .exp_cc = 0,
  87    },
  88    {
  89        .name = "rllg",
  90        .insn = rllg_0x697c9,
  91        .op1 = 0xaa2d54c1b729f7f4ull,
  92        .op2 = 0x5ffcf7465f5cd71full,
  93        .exp_result = 0x29f7f4aa2d54c1b7ull,
  94        .exp_cc = 0,
  95    },
  96    {
  97        .name = "sla-1",
  98        .insn = sla_0x4b0,
  99        .op1 = 0x8bf21fb67cca0e96ull,
 100        .op2 = 0x3ddf2f53347d3030ull,
 101        .exp_result = 0x8bf21fb600000000ull,
 102        .exp_cc = 3,
 103    },
 104    {
 105        .name = "sla-2",
 106        .insn = sla_0xd54,
 107        .op1 = 0xe4faaed5def0e926ull,
 108        .op2 = 0x18d586fab239cbeeull,
 109        .exp_result = 0xe4faaed5fbc3a498ull,
 110        .exp_cc = 3,
 111    },
 112    {
 113        .name = "slak",
 114        .insn = slak_0x2832c,
 115        .op1 = 0x7300bf78707f09f9ull,
 116        .op2 = 0x4d193b85bb5cb39bull,
 117        .exp_result = 0x7300bf783f84fc80ull,
 118        .exp_cc = 3,
 119    },
 120    {
 121        .name = "slag-1",
 122        .insn = slag_0x66cc4,
 123        .op1 = 0xe805966de1a77762ull,
 124        .op2 = 0x0e92953f6aa91c6bull,
 125        .exp_result = 0xbbb1000000000000ull,
 126        .exp_cc = 3,
 127    },
 128    {
 129        .name = "slag-2",
 130        .insn = slag_0xd54,
 131        .op1 = 0xdef0e92600000000ull,
 132        .op2 = 0x18d586fab239cbeeull,
 133        .exp_result = 0xfbc3a49800000000ull,
 134        .exp_cc = 3,
 135    },
 136    {
 137        .name = "sll",
 138        .insn = sll_0xd04,
 139        .op1 = 0xb90281a3105939dfull,
 140        .op2 = 0xb5e4df7e082e4c5eull,
 141        .exp_result = 0xb90281a300000000ull,
 142        .exp_cc = 0,
 143    },
 144    {
 145        .name = "sllk",
 146        .insn = sllk_0x2699f,
 147        .op1 = 0x777c6cf116f99557ull,
 148        .op2 = 0xe0556cf112e5a458ull,
 149        .exp_result = 0x777c6cf100000000ull,
 150        .exp_cc = 0,
 151    },
 152    {
 153        .name = "sllg",
 154        .insn = sllg_0x59df9,
 155        .op1 = 0xcdf86cbfbc0f3557ull,
 156        .op2 = 0x325a45acf99c6d3dull,
 157        .exp_result = 0x55c0000000000000ull,
 158        .exp_cc = 0,
 159    },
 160    {
 161        .name = "sra",
 162        .insn = sra_0x67e,
 163        .op1 = 0xb878f048d5354183ull,
 164        .op2 = 0x9e27d13195931f79ull,
 165        .exp_result = 0xb878f048ffffffffull,
 166        .exp_cc = 1,
 167    },
 168    {
 169        .name = "srak",
 170        .insn = srak_0x60943,
 171        .op1 = 0xb6ceb5a429cedb35ull,
 172        .op2 = 0x352354900ae34d7aull,
 173        .exp_result = 0xb6ceb5a400000000ull,
 174        .exp_cc = 0,
 175    },
 176    {
 177        .name = "srag",
 178        .insn = srag_0x6b048,
 179        .op1 = 0xd54dd4468676c63bull,
 180        .op2 = 0x84d026db7b4dca28ull,
 181        .exp_result = 0xffffffffffffd54dull,
 182        .exp_cc = 1,
 183    },
 184    {
 185        .name = "srl",
 186        .insn = srl_0x035,
 187        .op1 = 0x09be503ef826815full,
 188        .op2 = 0xbba8d1a0e542d5c1ull,
 189        .exp_result = 0x9be503e00000000ull,
 190        .exp_cc = 0,
 191    },
 192    {
 193        .name = "srlk",
 194        .insn = srlk_0x43dfc,
 195        .op1 = 0x540d6c8de71aee2aull,
 196        .op2 = 0x0000000000000000ull,
 197        .exp_result = 0x540d6c8d00000000ull,
 198        .exp_cc = 0,
 199    },
 200    {
 201        .name = "srlg",
 202        .insn = srlg_0x27227,
 203        .op1 = 0x26f7123c1c447a34ull,
 204        .op2 = 0x0000000000000000ull,
 205        .exp_result = 0x00000000004dee24ull,
 206        .exp_cc = 0,
 207    },
 208    {
 209        .name = "slda",
 210        .insn = slda_0x38b,
 211        .op1 = 0x7988f722dd5bbe7cull,
 212        .op2 = 0x9aed3f95b4d78cc2ull,
 213        .exp_result = 0x1ee45bab77cf8000ull,
 214        .exp_cc = 3,
 215    },
 216    {
 217        .name = "sldl",
 218        .insn = sldl_0x031,
 219        .op1 = 0xaae2918dce2b049aull,
 220        .op2 = 0x0000000000000000ull,
 221        .exp_result = 0x0934000000000000ull,
 222        .exp_cc = 0,
 223    },
 224    {
 225        .name = "srda",
 226        .insn = srda_0x36f,
 227        .op1 = 0x0cd4ed9228a50978ull,
 228        .op2 = 0x72b046f0848b8cc9ull,
 229        .exp_result = 0x000000000000000cull,
 230        .exp_cc = 2,
 231    },
 232    {
 233        .name = "srdl",
 234        .insn = srdl_0x99a,
 235        .op1 = 0x1018611c41689a1dull,
 236        .op2 = 0x2907e150c50ba319ull,
 237        .exp_result = 0x0000000000000203ull,
 238        .exp_cc = 0,
 239    },
 240};
 241
 242int main(void)
 243{
 244    int ret = 0;
 245    size_t i;
 246
 247    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
 248        uint64_t result;
 249        uint64_t cc = 0;
 250
 251        result = tests[i].insn(tests[i].op1, tests[i].op2, &cc);
 252        if (result != tests[i].exp_result) {
 253            fprintf(stderr,
 254                    "bad %s result:\n"
 255                    "actual   = 0x%" PRIx64 "\n"
 256                    "expected = 0x%" PRIx64 "\n",
 257                    tests[i].name, result, tests[i].exp_result);
 258            ret = 1;
 259        }
 260        if (cc != tests[i].exp_cc) {
 261            fprintf(stderr,
 262                    "bad %s cc:\n"
 263                    "actual   = %" PRIu64 "\n"
 264                    "expected = %" PRIu64 "\n",
 265                    tests[i].name, cc, tests[i].exp_cc);
 266            ret = 1;
 267        }
 268    }
 269    return ret;
 270}
 271