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