qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

shift.c (7636B)


      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 
     49 DEFINE_SHIFT_SINGLE_3(rll, 0x4cf3b);
     50 DEFINE_SHIFT_SINGLE_3(rllg, 0x697c9);
     51 DEFINE_SHIFT_SINGLE_2(sla, 0x4b0);
     52 DEFINE_SHIFT_SINGLE_2(sla, 0xd54);
     53 DEFINE_SHIFT_SINGLE_3(slak, 0x2832c);
     54 DEFINE_SHIFT_SINGLE_3(slag, 0x66cc4);
     55 DEFINE_SHIFT_SINGLE_3(slag, 0xd54);
     56 DEFINE_SHIFT_SINGLE_2(sll, 0xd04);
     57 DEFINE_SHIFT_SINGLE_3(sllk, 0x2699f);
     58 DEFINE_SHIFT_SINGLE_3(sllg, 0x59df9);
     59 DEFINE_SHIFT_SINGLE_2(sra, 0x67e);
     60 DEFINE_SHIFT_SINGLE_3(srak, 0x60943);
     61 DEFINE_SHIFT_SINGLE_3(srag, 0x6b048);
     62 DEFINE_SHIFT_SINGLE_2(srl, 0x035);
     63 DEFINE_SHIFT_SINGLE_3(srlk, 0x43dfc);
     64 DEFINE_SHIFT_SINGLE_3(srlg, 0x27227);
     65 DEFINE_SHIFT_DOUBLE(slda, 0x38b);
     66 DEFINE_SHIFT_DOUBLE(sldl, 0x031);
     67 DEFINE_SHIFT_DOUBLE(srda, 0x36f);
     68 DEFINE_SHIFT_DOUBLE(srdl, 0x99a);
     69 
     70 struct 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 
     79 static 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 
    242 int 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 }