Revision b0809bf7 tcg/ppc/tcg-target.c

b/tcg/ppc/tcg-target.c
316 316
#define STH    OPCD(44)
317 317
#define STW    OPCD(36)
318 318

  
319
#define ADDIC  OPCD(12)
319 320
#define ADDI   OPCD(14)
320 321
#define ADDIS  OPCD(15)
321 322
#define ORI    OPCD(24)
......
339 340
#define CRANDC XO19(129)
340 341
#define CRNAND XO19(225)
341 342
#define CROR   XO19(449)
343
#define CRNOR  XO19( 33)
342 344

  
343 345
#define EXTSB  XO31(954)
344 346
#define EXTSH  XO31(922)
......
365 367
#define MTSPR  XO31(467)
366 368
#define SRAWI  XO31(824)
367 369
#define NEG    XO31(104)
370
#define MFCR   XO31( 19)
371
#define CNTLZW XO31( 26)
368 372

  
369 373
#define LBZX   XO31( 87)
370 374
#define LHZX   XO31(279)
......
1065 1069
    }
1066 1070
}
1067 1071

  
1068
static void tcg_out_brcond (TCGContext *s, int cond,
1069
                            TCGArg arg1, TCGArg arg2, int const_arg2,
1070
                            int label_index)
1072
static void tcg_out_cr7eq_from_cond (TCGContext *s, const TCGArg *args,
1073
                                     const int *const_args)
1071 1074
{
1072
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1073
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
1074
}
1075

  
1076
/* XXX: we implement it at the target level to avoid having to
1077
   handle cross basic blocks temporaries */
1078
static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1079
                             const int *const_args)
1080
{
1081
    int cond = args[4], label_index = args[5], op;
1075
    int cond = args[4], op;
1082 1076
    struct { int bit1; int bit2; int cond2; } bits[] = {
1083 1077
        [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT  },
1084 1078
        [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT  },
......
1116 1110
    default:
1117 1111
        tcg_abort();
1118 1112
    }
1113
}
1114

  
1115
static void tcg_out_setcond (TCGContext *s, int cond, TCGArg arg0,
1116
                             TCGArg arg1, TCGArg arg2, int const_arg2)
1117
{
1118
    int crop, sh, arg;
1119

  
1120
    switch (cond) {
1121
    case TCG_COND_EQ:
1122
        if (const_arg2) {
1123
            if (!arg2) {
1124
                arg = arg1;
1125
            }
1126
            else {
1127
                arg = 0;
1128
                if ((uint16_t) arg2 == arg2) {
1129
                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1130
                }
1131
                else {
1132
                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1133
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1134
                }
1135
            }
1136
        }
1137
        else {
1138
            arg = 0;
1139
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1140
        }
1141
        tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
1142
        tcg_out32 (s, (RLWINM
1143
                       | RA (arg0)
1144
                       | RS (0)
1145
                       | SH (27)
1146
                       | MB (5)
1147
                       | ME (31)
1148
                       )
1149
            );
1150
        return;
1151

  
1152
    case TCG_COND_NE:
1153
        if (const_arg2) {
1154
            if (!arg2) {
1155
                arg = arg1;
1156
            }
1157
            else {
1158
                arg = 0;
1159
                if ((uint16_t) arg2 == arg2) {
1160
                    tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1161
                }
1162
                else {
1163
                    tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
1164
                    tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1165
                }
1166
            }
1167
        }
1168
        else {
1169
            arg = 0;
1170
            tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1171
        }
1172

  
1173
        if (arg == arg1 && arg1 == arg0) {
1174
            tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
1175
            tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
1176
        }
1177
        else {
1178
            tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
1179
            tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
1180
        }
1181
        return;
1182

  
1183
    case TCG_COND_LTU:
1184
    case TCG_COND_LT:
1185
        sh = 29;
1186
        crop = 0;
1187
        break;
1188

  
1189
    case TCG_COND_GEU:
1190
    case TCG_COND_GE:
1191
        sh = 31;
1192
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
1193
        break;
1194

  
1195
    case TCG_COND_LEU:
1196
    case TCG_COND_LE:
1197
        sh = 31;
1198
        crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
1199
        break;
1200

  
1201
    case TCG_COND_GTU:
1202
    case TCG_COND_GT:
1203
        sh = 30;
1204
        crop = 0;
1205
        break;
1206

  
1207
    default:
1208
        tcg_abort ();
1209
    }
1119 1210

  
1120
    tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), label_index);
1211
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1212
    if (crop) tcg_out32 (s, crop);
1213
    tcg_out32 (s, MFCR | RT (0));
1214
    tcg_out32 (s, (RLWINM
1215
                   | RA (arg0)
1216
                   | RS (0)
1217
                   | SH (sh)
1218
                   | MB (31)
1219
                   | ME (31)
1220
                   )
1221
        );
1222
}
1223

  
1224
static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
1225
                              const int *const_args)
1226
{
1227
    tcg_out_cr7eq_from_cond (s, args + 1, const_args + 1);
1228
    tcg_out32 (s, MFCR | RT (0));
1229
    tcg_out32 (s, (RLWINM
1230
                   | RA (args[0])
1231
                   | RS (0)
1232
                   | SH (31)
1233
                   | MB (31)
1234
                   | ME (31)
1235
                   )
1236
        );
1237
}
1238

  
1239
static void tcg_out_brcond (TCGContext *s, int cond,
1240
                            TCGArg arg1, TCGArg arg2, int const_arg2,
1241
                            int label_index)
1242
{
1243
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
1244
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
1245
}
1246

  
1247
/* XXX: we implement it at the target level to avoid having to
1248
   handle cross basic blocks temporaries */
1249
static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1250
                             const int *const_args)
1251
{
1252
    tcg_out_cr7eq_from_cond (s, args, const_args);
1253
    tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), args[5]);
1121 1254
}
1122 1255

  
1123 1256
void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
......
1496 1629
        tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
1497 1630
        break;
1498 1631

  
1632
    case INDEX_op_setcond_i32:
1633
        tcg_out_setcond (s, args[3], args[0], args[1], args[2], const_args[2]);
1634
        break;
1635
    case INDEX_op_setcond2_i32:
1636
        tcg_out_setcond2 (s, args, const_args);
1637
        break;
1638

  
1499 1639
    default:
1500 1640
        tcg_dump_ops (s, stderr);
1501 1641
        tcg_abort ();
......
1544 1684

  
1545 1685
    { INDEX_op_neg_i32, { "r", "r" } },
1546 1686

  
1687
    { INDEX_op_setcond_i32, { "r", "r", "ri" } },
1688
    { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
1689

  
1547 1690
#if TARGET_LONG_BITS == 32
1548 1691
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1549 1692
    { INDEX_op_qemu_ld8s, { "r", "L" } },

Also available in: Unified diff