196f47ace98da29eea520d4ea947c03f678496262sewardj
296f47ace98da29eea520d4ea947c03f678496262sewardj#define exec_op glue(exec_, OP)
396f47ace98da29eea520d4ea947c03f678496262sewardj#define exec_opq glue(glue(exec_, OP), q)
496f47ace98da29eea520d4ea947c03f678496262sewardj#define exec_opl glue(glue(exec_, OP), l)
596f47ace98da29eea520d4ea947c03f678496262sewardj#define exec_opw glue(glue(exec_, OP), w)
696f47ace98da29eea520d4ea947c03f678496262sewardj#define exec_opb glue(glue(exec_, OP), b)
796f47ace98da29eea520d4ea947c03f678496262sewardj
896f47ace98da29eea520d4ea947c03f678496262sewardj#ifndef OP_SHIFTD
996f47ace98da29eea520d4ea947c03f678496262sewardj
1096f47ace98da29eea520d4ea947c03f678496262sewardj#ifdef OP_NOBYTE
1196f47ace98da29eea520d4ea947c03f678496262sewardj#define EXECSHIFT(size, res, s1, s2, flags) \
1296f47ace98da29eea520d4ea947c03f678496262sewardj    asm ("pushq %4\n\t"\
1396f47ace98da29eea520d4ea947c03f678496262sewardj         "popfq\n\t"\
1496f47ace98da29eea520d4ea947c03f678496262sewardj         stringify(OP) size " %" size "2, %" size "0\n\t" \
1596f47ace98da29eea520d4ea947c03f678496262sewardj         "pushfq\n\t"\
1696f47ace98da29eea520d4ea947c03f678496262sewardj         "popq %1\n\t"\
1796f47ace98da29eea520d4ea947c03f678496262sewardj         : "=g" (res), "=g" (flags)\
1896f47ace98da29eea520d4ea947c03f678496262sewardj         : "r" (s1), "0" (res), "1" (flags));
1996f47ace98da29eea520d4ea947c03f678496262sewardj#else
2096f47ace98da29eea520d4ea947c03f678496262sewardj#define EXECSHIFT(size, res, s1, s2, flags) \
2196f47ace98da29eea520d4ea947c03f678496262sewardj    asm ("pushq %4\n\t"\
2296f47ace98da29eea520d4ea947c03f678496262sewardj         "popfq\n\t"\
2396f47ace98da29eea520d4ea947c03f678496262sewardj         stringify(OP) size " %%cl, %" size "0\n\t" \
2496f47ace98da29eea520d4ea947c03f678496262sewardj         "pushfq\n\t"\
2596f47ace98da29eea520d4ea947c03f678496262sewardj         "popq %1\n\t"\
2696f47ace98da29eea520d4ea947c03f678496262sewardj         : "=q" (res), "=g" (flags)\
2796f47ace98da29eea520d4ea947c03f678496262sewardj         : "c" (s1), "0" (res), "1" (flags));
2896f47ace98da29eea520d4ea947c03f678496262sewardj#endif
2996f47ace98da29eea520d4ea947c03f678496262sewardj
3096f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_opq(int64 s2, int64 s0, int64 s1, int64 iflags)
3196f47ace98da29eea520d4ea947c03f678496262sewardj{
3296f47ace98da29eea520d4ea947c03f678496262sewardj    int64 res, flags;
3396f47ace98da29eea520d4ea947c03f678496262sewardj    res = s0;
3496f47ace98da29eea520d4ea947c03f678496262sewardj    flags = iflags;
3596f47ace98da29eea520d4ea947c03f678496262sewardj    EXECSHIFT("q", res, s1, s2, flags);
3696f47ace98da29eea520d4ea947c03f678496262sewardj    /* overflow is undefined if count != 1 */
3796f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 != 1)
3896f47ace98da29eea520d4ea947c03f678496262sewardj      flags &= ~CC_O;
3996f47ace98da29eea520d4ea947c03f678496262sewardj    printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
4096f47ace98da29eea520d4ea947c03f678496262sewardj           stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK);
4196f47ace98da29eea520d4ea947c03f678496262sewardj}
4296f47ace98da29eea520d4ea947c03f678496262sewardj
4396f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_opl(int64 s2, int64 s0, int64 s1, int64 iflags)
4496f47ace98da29eea520d4ea947c03f678496262sewardj{
4596f47ace98da29eea520d4ea947c03f678496262sewardj    int64 res, flags;
4696f47ace98da29eea520d4ea947c03f678496262sewardj    res = s0;
4796f47ace98da29eea520d4ea947c03f678496262sewardj    flags = iflags;
4896f47ace98da29eea520d4ea947c03f678496262sewardj    EXECSHIFT("", res, s1, s2, flags);
4996f47ace98da29eea520d4ea947c03f678496262sewardj    /* overflow is undefined if count != 1 */
5096f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 != 1)
5196f47ace98da29eea520d4ea947c03f678496262sewardj      flags &= ~CC_O;
5296f47ace98da29eea520d4ea947c03f678496262sewardj    printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
5396f47ace98da29eea520d4ea947c03f678496262sewardj           stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
5496f47ace98da29eea520d4ea947c03f678496262sewardj}
5596f47ace98da29eea520d4ea947c03f678496262sewardj
5696f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_opw(int64 s2, int64 s0, int64 s1, int64 iflags)
5796f47ace98da29eea520d4ea947c03f678496262sewardj{
5896f47ace98da29eea520d4ea947c03f678496262sewardj    int64 res, flags;
5996f47ace98da29eea520d4ea947c03f678496262sewardj    res = s0;
6096f47ace98da29eea520d4ea947c03f678496262sewardj    flags = iflags;
6196f47ace98da29eea520d4ea947c03f678496262sewardj    EXECSHIFT("w", res, s1, s2, flags);
6296f47ace98da29eea520d4ea947c03f678496262sewardj    /* overflow is undefined if count != 1 */
6396f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 != 1)
6496f47ace98da29eea520d4ea947c03f678496262sewardj      flags &= ~CC_O;
6596f47ace98da29eea520d4ea947c03f678496262sewardj    printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
6696f47ace98da29eea520d4ea947c03f678496262sewardj           stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
6796f47ace98da29eea520d4ea947c03f678496262sewardj}
6896f47ace98da29eea520d4ea947c03f678496262sewardj
6996f47ace98da29eea520d4ea947c03f678496262sewardj#else
7096f47ace98da29eea520d4ea947c03f678496262sewardj#define EXECSHIFT(size, res, s1, s2, flags) \
7196f47ace98da29eea520d4ea947c03f678496262sewardj    asm ("pushq %4\n\t"\
7296f47ace98da29eea520d4ea947c03f678496262sewardj         "popfq\n\t"\
7396f47ace98da29eea520d4ea947c03f678496262sewardj         stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \
7496f47ace98da29eea520d4ea947c03f678496262sewardj         "pushfq\n\t"\
7596f47ace98da29eea520d4ea947c03f678496262sewardj         "popq %1\n\t"\
7696f47ace98da29eea520d4ea947c03f678496262sewardj         : "=g" (res), "=g" (flags)\
7796f47ace98da29eea520d4ea947c03f678496262sewardj         : "c" (s1), "0" (res), "1" (flags), "r" (s2));
7896f47ace98da29eea520d4ea947c03f678496262sewardj
7996f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_opl(int64 s2, int64 s0, int64 s1, int64 iflags)
8096f47ace98da29eea520d4ea947c03f678496262sewardj{
8196f47ace98da29eea520d4ea947c03f678496262sewardj    int64 res, flags;
8296f47ace98da29eea520d4ea947c03f678496262sewardj    res = s0;
8396f47ace98da29eea520d4ea947c03f678496262sewardj    flags = iflags;
8496f47ace98da29eea520d4ea947c03f678496262sewardj    EXECSHIFT("", res, s1, s2, flags);
8596f47ace98da29eea520d4ea947c03f678496262sewardj    /* overflow is undefined if count != 1 */
8696f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 != 1)
8796f47ace98da29eea520d4ea947c03f678496262sewardj      flags &= ~CC_O;
8896f47ace98da29eea520d4ea947c03f678496262sewardj    printf("%-10s A=%016llx B=%016llx C=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
8996f47ace98da29eea520d4ea947c03f678496262sewardj           stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
9096f47ace98da29eea520d4ea947c03f678496262sewardj}
9196f47ace98da29eea520d4ea947c03f678496262sewardj
9296f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_opw(int64 s2, int64 s0, int64 s1, int64 iflags)
9396f47ace98da29eea520d4ea947c03f678496262sewardj{
9496f47ace98da29eea520d4ea947c03f678496262sewardj    int64 res, flags;
9596f47ace98da29eea520d4ea947c03f678496262sewardj    res = s0;
9696f47ace98da29eea520d4ea947c03f678496262sewardj    flags = iflags;
9796f47ace98da29eea520d4ea947c03f678496262sewardj    EXECSHIFT("w", res, s1, s2, flags);
9896f47ace98da29eea520d4ea947c03f678496262sewardj    /* overflow is undefined if count != 1 */
9996f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 != 1)
10096f47ace98da29eea520d4ea947c03f678496262sewardj      flags &= ~CC_O;
10196f47ace98da29eea520d4ea947c03f678496262sewardj    printf("%-10s A=%016llx B=%016llx C=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
10296f47ace98da29eea520d4ea947c03f678496262sewardj           stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
10396f47ace98da29eea520d4ea947c03f678496262sewardj}
10496f47ace98da29eea520d4ea947c03f678496262sewardj
10596f47ace98da29eea520d4ea947c03f678496262sewardj#endif
10696f47ace98da29eea520d4ea947c03f678496262sewardj
10796f47ace98da29eea520d4ea947c03f678496262sewardj#ifndef OP_NOBYTE
10896f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_opb(int64 s0, int64 s1, int64 iflags)
10996f47ace98da29eea520d4ea947c03f678496262sewardj{
11096f47ace98da29eea520d4ea947c03f678496262sewardj    int64 res, flags;
11196f47ace98da29eea520d4ea947c03f678496262sewardj    res = s0;
11296f47ace98da29eea520d4ea947c03f678496262sewardj    flags = iflags;
11396f47ace98da29eea520d4ea947c03f678496262sewardj    EXECSHIFT("b", res, s1, 0, flags);
11496f47ace98da29eea520d4ea947c03f678496262sewardj    /* overflow is undefined if count != 1 */
11596f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 != 1)
11696f47ace98da29eea520d4ea947c03f678496262sewardj      flags &= ~CC_O;
11796f47ace98da29eea520d4ea947c03f678496262sewardj    printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n",
11896f47ace98da29eea520d4ea947c03f678496262sewardj           stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
11996f47ace98da29eea520d4ea947c03f678496262sewardj}
12096f47ace98da29eea520d4ea947c03f678496262sewardj#endif
12196f47ace98da29eea520d4ea947c03f678496262sewardj
12296f47ace98da29eea520d4ea947c03f678496262sewardjvoid exec_op(int64 s2, int64 s0, int64 s1)
12396f47ace98da29eea520d4ea947c03f678496262sewardj{
12496f47ace98da29eea520d4ea947c03f678496262sewardj  int64 o,s,z,a,c,p,flags_in;
12596f47ace98da29eea520d4ea947c03f678496262sewardj  for (o = 0; o < 2; o++) {
12696f47ace98da29eea520d4ea947c03f678496262sewardj  for (s = 0; s < 2; s++) {
12796f47ace98da29eea520d4ea947c03f678496262sewardj  for (z = 0; z < 2; z++) {
12896f47ace98da29eea520d4ea947c03f678496262sewardj  for (a = 0; a < 2; a++) {
12996f47ace98da29eea520d4ea947c03f678496262sewardj  for (c = 0; c < 2; c++) {
13096f47ace98da29eea520d4ea947c03f678496262sewardj  for (p = 0; p < 2; p++) {
13196f47ace98da29eea520d4ea947c03f678496262sewardj
13296f47ace98da29eea520d4ea947c03f678496262sewardj    flags_in = (o ? CC_O : 0)
13396f47ace98da29eea520d4ea947c03f678496262sewardj             | (s ? CC_S : 0)
13496f47ace98da29eea520d4ea947c03f678496262sewardj             | (z ? CC_Z : 0)
13596f47ace98da29eea520d4ea947c03f678496262sewardj             | (a ? CC_A : 0)
13696f47ace98da29eea520d4ea947c03f678496262sewardj             | (c ? CC_C : 0)
13796f47ace98da29eea520d4ea947c03f678496262sewardj             | (p ? CC_P : 0);
13896f47ace98da29eea520d4ea947c03f678496262sewardj
13996f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opq(s2, s0, s1, flags_in);
14096f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 <= 31)
14196f47ace98da29eea520d4ea947c03f678496262sewardj       exec_opl(s2, s0, s1, flags_in);
14296f47ace98da29eea520d4ea947c03f678496262sewardj#ifdef OP_SHIFTD
14396f47ace98da29eea520d4ea947c03f678496262sewardj    if (s1 <= 15)
14496f47ace98da29eea520d4ea947c03f678496262sewardj        exec_opw(s2, s0, s1, flags_in);
14596f47ace98da29eea520d4ea947c03f678496262sewardj#else
14696f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opw(s2, s0, s1, flags_in);
14796f47ace98da29eea520d4ea947c03f678496262sewardj#endif
14896f47ace98da29eea520d4ea947c03f678496262sewardj#ifndef OP_NOBYTE
14996f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opb(s0, s1, flags_in);
15096f47ace98da29eea520d4ea947c03f678496262sewardj#endif
15196f47ace98da29eea520d4ea947c03f678496262sewardj#ifdef OP_CC
15296f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opq(s2, s0, s1, flags_in);
15396f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opl(s2, s0, s1, flags_in);
15496f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opw(s2, s0, s1, flags_in);
15596f47ace98da29eea520d4ea947c03f678496262sewardj    exec_opb(s0, s1, flags_in);
15696f47ace98da29eea520d4ea947c03f678496262sewardj#endif
15796f47ace98da29eea520d4ea947c03f678496262sewardj
15896f47ace98da29eea520d4ea947c03f678496262sewardj  }}}}}}
15996f47ace98da29eea520d4ea947c03f678496262sewardj
16096f47ace98da29eea520d4ea947c03f678496262sewardj}
16196f47ace98da29eea520d4ea947c03f678496262sewardj
16296f47ace98da29eea520d4ea947c03f678496262sewardjvoid glue(test_, OP)(void)
16396f47ace98da29eea520d4ea947c03f678496262sewardj{
16496f47ace98da29eea520d4ea947c03f678496262sewardj    int64 i;
16596f47ace98da29eea520d4ea947c03f678496262sewardj    for(i = 0; i < 64; i++)
16696f47ace98da29eea520d4ea947c03f678496262sewardj        exec_op(0x3141592721ad3d34, 0x2718284612345678, i);
16796f47ace98da29eea520d4ea947c03f678496262sewardj    for(i = 0; i < 64; i++)
16896f47ace98da29eea520d4ea947c03f678496262sewardj        exec_op(0x31415927813f3421, 0x2718284682345678, i);
16996f47ace98da29eea520d4ea947c03f678496262sewardj}
17096f47ace98da29eea520d4ea947c03f678496262sewardj
17196f47ace98da29eea520d4ea947c03f678496262sewardjvoid *glue(_test_, OP) __init_call = glue(test_, OP);
17296f47ace98da29eea520d4ea947c03f678496262sewardj
17396f47ace98da29eea520d4ea947c03f678496262sewardj#undef OP
17496f47ace98da29eea520d4ea947c03f678496262sewardj#undef OP_CC
17596f47ace98da29eea520d4ea947c03f678496262sewardj#undef OP_SHIFTD
17696f47ace98da29eea520d4ea947c03f678496262sewardj#undef OP_NOBYTE
17796f47ace98da29eea520d4ea947c03f678496262sewardj#undef EXECSHIFT
17896f47ace98da29eea520d4ea947c03f678496262sewardj
179